Сжатие и полная запись IPv6

Сократите адрес IPv6 до единственной канонической формы или разверните его до всех 32 цифр и посмотрите, какие нули уходят, почему одна серия стала :: и какое правило RFC 5952 нарушила ваша запись. Списки тоже поддерживаются.

Каноническая запись по RFC 5952 · разбор по RFC 4291, включая IPv4 в конце адреса · работает в вашем браузере

Прочитано как IPv6

8 групп и то, что убирает сжатиеСимволов: 39 → 17 · на 22 символа меньше
сохраненоведущий ноль, убрансерия, которая станет ::другие нули, сохранены
Примеры

Один адрес или список, по одному в строке (до 100). Преобразование идёт в вашем браузере, ничего не отправляется.

Применено 3 правилаRFC 5952

2001:db8::1:0:0:1

Две серии из 2 нулевых групп: первая стала ::

RFC 5952, правило за правилом

Ведущие нули убраны§4.1Исправлено0DB8 → db8, 0001 → 1, 0000 → 0, 0000 → 0
:: максимально длинный§4.2.1Исправлено0000:0000 записано полностью → ::
Без :: для одной группы§4.2.2Выполнено
Самая длинная серия, при равенстве первая§4.2.3ВыполненоДве серии из 2 нулевых групп: первая стала ::
Строчные буквы§4.3Исправлено0DB8 → db8
Сжатая запись (RFC 5952)
Полная запись
В URL
В виде числа
Десятичный · hex · двоичный
Имя для обратного DNS

Как сжать адрес IPv6?

Переведите его в строчные буквы, уберите ведущие нули в каждой группе, затем замените самую длинную серию из двух и более нулевых групп на ::, а если две серии одинаковой длины — первую из них.

Так получается единственная каноническая форма, которую RFC 5952 требует выводить программам. При этом на входе программы обязаны принимать любую другую допустимую запись, так что сжатие никогда не меняет адрес — только то, как он записан.

2001:0DB8:0000:0000:0000:FF00:0042:8329 сокращается до 2001:db8::ff00:42:8329, шаг за шагом.
Сжатие IPv6: инструмент показывает нули, которые убирает RFC 5952, и серию, которая становится ::Сжатие IPv6: инструмент показывает нули, которые убирает RFC 5952, и серию, которая становится ::Что вы ввелиВерхний регистр, ведущие нули и всё прочее: любая допустимая запись распознаётся.Убранные нулиВедущие нули зачёркнуты, группа за группой.Серия, которая становится ::Самая длинная серия нулевых групп; при равенстве — первая.Серии, которые остаютсяДругие серии нулей сохраняют свои 0, с указанием причины.Правило за правиломСколько правил RFC 5952 нарушила запись; список под ним называет каждое и то, что изменилось.
Две равные серии нулей: RFC 5952 сжимает первую, а список правил называет каждое правило, которое нарушила запись.

Каковы правила сжатия IPv6 по RFC 5952?

RFC 5952 задаёт пять правил: убирать ведущие нули, делать :: как можно длиннее, никогда не использовать :: для одной нулевой группы, сжимать самую длинную серию (при равенстве — первую) и писать шестнадцатеричные буквы строчными.

Шестая рекомендация касается адресов, которые несут IPv4: после префикса вроде ::ffff: последние 32 бита записываются как адрес IPv4 с точками. Инструмент сверяет каждое правило с тем, что вы ввели, и называет исправленные.

1Ведущие нули убраны§4.1

Правильно: 2001:db8::1

Неправильно: 2001:0db8::0001

2:: максимально длинный§4.2.1

Правильно: 2001:db8::2:1

Неправильно: 2001:db8:0:0:0:0:2:1

3Без :: для одной группы§4.2.2

Правильно: 2001:db8:0:1:1:1:1:1

Неправильно: 2001:db8::1:1:1:1:1

4Самая длинная серия, при равенстве первая§4.2.3

Правильно: 2001:db8::1:0:0:1

Неправильно: 2001:db8:0:0:1::1

5Строчные буквы§4.3

Правильно: 2001:db8::a

Неправильно: 2001:DB8::A

+IPv4 с точками в конце§5

Правильно: ::ffff:192.0.2.1

Неправильно: 0:0:0:0:0:ffff:192.0.2.1

Каждое правило с собственными примерами RFC 5952: как правильно и как нет.

Как развернуть адрес IPv6 до полной записи?

Посчитайте записанные группы, пусть :: заменяет столько нулевых групп, сколько нужно до восьми, и дополните каждую группу до четырёх цифр: в 2001:db8::1 три группы, значит, :: — это пять.

Полная запись нужна обратному DNS, где адрес идёт по одной цифре (ниблу), а также многим журналам и таблицам для сортировки как текста. В Python она называется .exploded, в Go — StringExpanded.

Полная запись 2001:db8::1: 3 записанные группы, 5 нулевых групп вместо ::, каждая группа дополнена.

Сколькими способами можно записать один адрес IPv6?

Многими: ведущие нули, регистр букв и место :: могут меняться, так что у одного адреса много допустимых записей, и RFC 5952 перечисляет восемь для 2001:db8:0:0:1:0:0:1, прежде чем зафиксировать одну каноническую форму.

Поэтому сравнение адресов как текста не работает: две записи одного адреса не совпадают. Сравнивайте их как 128-битные числа или сначала сожмите обе.

2001:db8:0:0:1:0:0:12001:0db8:0:0:1:0:0:12001:db8::1:0:0:12001:db8::0:1:0:0:12001:0db8::1:0:0:12001:db8:0:0:1::12001:db8:0000:0:1::12001:DB8:0:0:1::1
2001:db8::1:0:0:1каноническая · RFC 5952
Восемь вариантов записи из RFC 5952, один адрес.

Как записать адрес IPv6 в URL, с портом или зоной?

Заключите адрес в квадратные скобки, http://[2001:db8::1]:8443/, чтобы порт нельзя было принять за группу; зону вроде %eth0 в URL браузера указать вообще нельзя.

RFC 5952 предписывает брать в скобки адрес с портом и называет запись 2001:db8::1:8443 нерекомендуемой. Больше ни для чего скобки в URL не используются. Браузеры выводят адрес в hex даже после ::ffff:, так что [::ffff:192.0.2.1] отображается как [::ffff:c000:201].

Зона обозначает интерфейс на одном компьютере, например fe80::1%eth0. RFC 9844 в 2025 году снова убрал зоны из URL, и браузеры их отклоняют, хотя программы по-прежнему должны позволять ввести зону.

http://схема[2001:db8::1]IPv6 в скобках:8443порт/statusпуть

Зона (%eth0) · fe80::1%eth0

Ввод в поле программыразрешена
В URL браузераотклоняется
inet_pton()не может её разобрать
Глобальные адресаеё никогда не имеют
URL с адресом IPv6 по частям и где может стоять зона.

Как сжать или развернуть IPv6 в коде?

Разберите адрес и выведите его: .compressed в Python, netip.Addr.String() в Go и INET6_NTOA(INET6_ATON(…)) в MySQL дают каноническую запись, а .exploded и StringExpanded() — полную.

str() в Python тоже возвращает сжатую форму, а суффикс %zone Python принимает. MySQL выводит строчные буквы, не больше 39 символов, одинаково на всех платформах.

› import ipaddress
a = ipaddress.ip_address('2001:0DB8::0001')
a.compressed, a.exploded
('2001:db8::1', '2001:0db8:0000:0000:0000:0000:0000:0001')

Python ipaddress

› a := netip.MustParseAddr("2001:0DB8::0001")
fmt.Println(a.String(), a.StringExpanded())
2001:db8::1 2001:0db8:0000:0000:0000:0000:0000:0001

Go net/netip

› SELECT INET6_NTOA(INET6_ATON('2001:0DB8::0001'));
2001:db8::1

MySQL 8.4

Каноническая сжатая запись и полная запись из Python, Go и MySQL.

Частые вопросы

Какая сжатая форма у 2001:0db8:0000:0000:0000:ff00:0042:8329?

2001:db8::ff00:42:8329. Переведите буквы в строчные, уберите ведущие нули каждой группы (0db8 становится db8, 0042 — 42), затем замените серию из трёх нулевых групп на ::. Получается 22 символа вместо 39, и это единственная форма, которую RFC 5952 называет канонической. Развернув её снова, вы получите ровно те же 32 шестнадцатеричные цифры.

Можно ли использовать :: в адресе IPv6 дважды?

Нет. :: заменяет одну или несколько нулевых групп и может встречаться только один раз: при двух никто не смог бы сказать, сколько групп заменяет каждый, поэтому 2001:db8::1::1 недопустим. Если в адресе две серии нулей, сожмите более длинную, а при равной длине — первую, а другую запишите как 0:0, например 2001:db8::1:0:0:1.

Почему 2001:db8:0:1:1:1:1:1 не сжимается до 2001:db8::1:1:1:1:1?

Потому что RFC 5952 запрещает использовать :: для одной нулевой группы. Такое сокращение сэкономило бы один символ и ухудшило бы читаемость, поэтому каноническая форма оставляет одиночную группу как 0: 2001:db8:0:1:1:1:1:1. Парсеры по-прежнему принимают 2001:db8::1:1:1:1:1 как тот же адрес, но программы никогда не должны выводить его в таком виде.

Адреса IPv6 пишутся заглавными или строчными буквами?

Строчными. RFC 5952 требует для канонической формы шестнадцатеричные буквы от a до f в нижнем регистре, и браузеры и большинство библиотек выводят их именно так. Ввод в верхнем регистре программы всё равно должны принимать, так что 2001:DB8::A и 2001:db8::a — один и тот же адрес; меняется только выводимая форма. Верхний регистр часто встречается в старой документации и в конфигурационных файлах некоторых производителей.

Как развернуть :: в адресе IPv6?

Посчитайте записанные группы, и пусть :: заменяет столько нулевых групп, сколько нужно до восьми. В 2001:db8::ff00:42:8329 записано пять групп, значит, :: — это три группы 0000. Дополните каждую группу до четырёх цифр и получите 2001:0db8:0000:0000:0000:ff00:0042:8329 — полную запись, которую используют обратный DNS и многие инструменты для журналов.

Сколько символов в самом длинном адресе IPv6?

39 в полной шестнадцатеричной форме: восемь групп по четыре цифры и семь двоеточий. Форма с IPv4 в конце может быть длиннее, поэтому размер буфера INET6_ADDRSTRLEN в API сокетов — 46 байт: этого хватает на 0000:0000:0000:0000:0000:ffff:255.255.255.255 и завершающий NUL. Сжатые адреса обычно намного короче; адрес :: занимает всего два символа.

Почему ::ffff:c000:280 превращается в ::ffff:192.0.2.128?

Потому что RFC 5952 рекомендует записывать последние 32 бита отображённого адреса IPv4 как адрес IPv4 с точками: именно это эти биты и означают. Оба написания — один и тот же адрес, и оба допустимы на входе. Исключение — браузеры: URL Standard всегда выводит форму в hex, поэтому в адресной строке тот же адрес выглядит как [::ffff:c000:280].

Как указать адрес IPv6 с портом в URL?

Заключите адрес в квадратные скобки, а порт поставьте после них: http://[2001:db8::1]:8443/. Без скобок порт выглядел бы как ещё одна группа, поэтому RFC 5952 не рекомендует писать 2001:db8::1:8443. Скобки в URL используются только для литералов IPv6. Зону вроде %eth0 в URL браузера указать вообще нельзя: браузеры её отклоняют.

Как сжать адрес IPv6 в Python?

Разберите его модулем ipaddress и возьмите .compressed для канонической короткой формы или .exploded для всех 32 цифр: ipaddress.ip_address('2001:0db8::0001').compressed даёт '2001:db8::1', и str() возвращает то же самое. В Go ту же задачу решают String() и StringExpanded() у netip.Addr, а INET6_NTOA(INET6_ATON(…)) в MySQL выводит каноническую запись строчными буквами.

Можно ли сжать сразу список адресов IPv6?

Да. Вставьте до 100 адресов, по одному в строке, и инструмент переключится на таблицу со сжатой и полной формой каждой строки и правилами RFC 5952, которые нарушила её запись. Строки, которые не являются адресами, помечаются, а не выбрасываются, так что строки таблицы по-прежнему соответствуют вашему вводу. Скопируйте любой столбец или скачайте CSV; ничего не покидает ваш браузер.