Максимальная длина текстового представления адреса IPv6?

430

Я хочу сохранить данные, возвращаемые $_SERVER["REMOTE_ADDR"]PHP, в поле БД, на самом деле довольно простая задача. Проблема в том, что я не могу найти какую-либо правильную информацию о максимальной длине текстового представления адреса IPv6, что обеспечивает веб-сервер $_SERVER["REMOTE_ADDR"].

Меня не интересует преобразование текстового представления в 128 битов, в которые обычно кодируется адрес, я просто хочу знать, сколько символов максимально необходимо для хранения любого адреса IPv6, возвращаемого $_SERVER["REMOTE_ADDR"].

жилль
источник
6
Что насчет индекса зоны?
Роберт Тупело-Шнек
5
#define INET_ADDRSTRLEN (16) #define INET6_ADDRSTRLEN (48)
Источник: lxr.free-electrons.com/source/include/linux/inet.h
1
Вопрос stackoverflow.com/questions/1076714/… имеет несколько похожих, но полезных ответов.
Эдвард

Ответы:

615

45 символов .

Вы можете ожидать, что адрес будет

0000:0000:0000:0000:0000:0000:0000:0000

8 * 4 + 7 = 39

8 групп по 4 цифры с 7 :между ними.

Но если у вас есть IPv4-сопоставленный адрес IPv6 , последние две группы можно записать в базу 10, разделив ., например, [::ffff:192.168.100.228], Выписано полностью:

0000:0000:0000:0000:0000:ffff:192.168.100.228

(6 * 4 + 5) + 1 + (4 * 3 + 3) = 29 + 1 + 15 = 45

Обратите внимание, что это соглашение ввода / вывода - это по-прежнему 128-битный адрес, и для хранения, вероятно, было бы лучше стандартизировать формат с необработанным двоеточием, то есть [0000:0000:0000:0000:0000:ffff:c0a8:64e4]для указанного выше адреса.

Мэтью Шарли
источник
245
В заголовочных файлах для INET6_ADDRSTRLEN задано значение 46, что соответствует 45 символам плюс завершающий ноль.
Висний
6
Стоит отметить, что IPv6-адрес также может содержать область видимости stackoverflow.com/questions/5746082/… , например, вы получаете это из RemoteEndpointMessageProperty.Address
Rory
адреса ipv4 не написаны как :: ffff: 127.0.0.1?
серый волк
52
@FelipeSchenone это такое мышление, которое бесполезно - выяснить размер и использовать его. Единственный раз, когда вы хотите расширить буфер, это если он помогает с заполнением, так что 64 символа, но 45 (+1) является оптимальным.
gbjbaanb
1
это учитывает процент входа в адрес ipv6? Обращайтесь - superuser.com/questions/99746/…
gaurav
85

В Linux смотрите константу INET6_ADDRSTRLEN(включайте <arpa/inet.h>, смотрите man inet_ntop). В моей системе (заголовок "in.h"):

#define INET6_ADDRSTRLEN 46

Последний символ предназначен для завершения NULL, как я полагаю, поэтому максимальная длина составляет 45, как и другие ответы.

Юрий
источник
2
Так что же это за 48 я вижу? github.com/torvalds/linux/blob/master/include/linux/inet.h#L50
EIS
@eis, вероятно, был в 2013 году. Возможно, увеличен для выравнивания структуры.
Ииридайн
13

Ответил на мой вопрос:

Адреса IPv6 обычно записываются в виде восьми групп из четырех шестнадцатеричных цифр, где каждая группа разделяется двоеточием (:).

Так что это максимум 39 символов.

жилль
источник
7
Однако, очевидно, есть предостережение, см. Stackoverflow.com/a/7477384/3787376 («Максимальная длина для IP-адреса клиента») - Цитата: «Для сопоставленных IPv4-адресов IPv6 строка может быть длиннее 39 символов». В нем говорится, что «IPv4-сопоставленный IPv6» имеет 45 символов и имеет формат «NNNN: NNNN: NNNN: NNNN: NNNN: NNNN: 192.168.158.190». Следовательно, максимум должен быть 45 символов. Ответ на stackoverflow.com/a/166157/3787376 (этот вопрос) также, кажется, демонстрирует эту точку зрения.
Эдвард
6

Я думаю, что ответ @Deepak в этой ссылке более близок к правильному ответу. Максимальная длина для IP-адреса клиента . Таким образом, правильный размер - 45, а не 39. Иногда мы пытаемся найти размер полей, но лучше подготовить достаточно места для хранения.

Qmaster
источник
4

Как указано, стандартный адрес ipv6 составляет не более 45 символов, но адрес ipv6 также может включать в себя конечный%, за которым следует строка «scope» или «zone», которая не имеет фиксированной длины, но обычно представляет собой небольшое положительное целое число или сетевой интерфейс. имя, так что на самом деле это может быть больше, чем 45 символов. Имена сетевых интерфейсов, как правило, имеют вид «eth0», «eth1», «wlan0», поэтому выбор 50 в качестве предела, вероятно, достаточно хорош.

Шон Ф
источник
3
Да, но это только локальные адреса ссылок, и вы не увидите ни одного из них, когда ваш сайт будет работать в Интернете (и, надеюсь, даже при его разработке).
Майкл Хэмптон
1

Следите за тем, чтобы определенные заголовки, например HTTP_X_FORWARDED_FOR, содержали один IP-адрес. Они могут содержать несколько адресов (я полагаю, цепочку прокси).

Они будут выглядеть разделенными запятыми - и могут быть намного длиннее, чем 45 символов - поэтому проверьте перед сохранением в БД.

Simon_Weaver
источник
3
Слегка конфликтующий -1 (конфликтующий, потому что я попадал в эту ловушку раньше, и я думаю, что этот ответ содержит информацию, относящуюся к некоторым людям, которые будут появляться на этой странице), потому что, тем не менее, это явно не ответ на заданный вопрос. Вероятно, было бы лучше в качестве комментария на вопрос.
Марк Эмери