Компилятор XLC IBM имеет "initauto" опцию, которая присвоит автоматическим переменным значение, которое Вы определяете. Я использовал следующее для своих сборок отладки:
-Wc,'initauto(deadbeef,word)'
, Если бы я посмотрел на устройство хранения данных неинициализированной переменной, оно было бы установлено на 0xdeadbeef
В системах POSIX вы можете использовать inet_pton
и inet_ntop
в комбинации для выполнения канонизации. Вам все равно придется выполнить собственный синтаксический анализ CIDR. К счастью, я считаю, что единственным допустимым синтаксисом CIDR для IPv6 является нотация / number_of_bits, так что это довольно просто.
Другая проблема, с которой вы столкнетесь, - это отсутствие поддержки спецификаций интерфейса. Для локальных для ссылки адресов вы увидите в конце такие вещи, как % eth0
, чтобы указать, какая ссылка они также являются локальными. getaddrinfo
проанализирует это, а inet_pton
- нет.
Одна из стратегий, которую вы можете использовать, - это использовать getaddrinfo
для анализа и inet_ntop
канонизировать.
getaddrinfo
доступен для Windows. inet_pton
и inet_ntop
не являются. К счастью, написать код для создания IPv6-адреса канонической формы не так уж и сложно. Однако для этого потребуется два прохода, потому что правило сжатия 0 - это самая большая строка из нулей, которая встречается первой. Также форма IPv4 (например, :: 127.0.0.1
) используется только для :: IPv4
или :: ffff: IPv4
.
У меня нет компьютера с Windows для тестирования, но из документации видно, что Python в Windows поддерживает inet_pton
и ] inet_ntop
в своем модуле сокета.
Написание собственной процедуры для создания канонической формы может быть неплохой идеей, поскольку даже если ваша каноническая форма не такая же, как у всех остальных, при условии, что она действительна, other люди могут разбирать это. Но я бы ни при каких обстоятельствах не стал писать вашу собственную процедуру для синтаксического анализа адресов IPv6.
Мой совет, приведенный выше, подходит для Python, C и C ++. Я почти ничего не знаю о том, как решить эту проблему в Java или Javascript.
РЕДАКТИРОВАТЬ : Я изучал getaddrinfo и его аналог, getnameinfo. Они почти во всех отношениях лучше, чем inet_pton
и inet_ntop
. Они являются потокобезопасными, и вы можете передавать им параметры ( AI_NUMERICHOST
в случае getaddrinfo
] и NI_NUMERCHOST
в случае getnameinfo
), чтобы они не могли выполнять какие-либо DNS-запросы. Их интерфейс немного сложен и в некоторых отношениях напоминает мне уродливый интерфейс Windows, но довольно легко понять, какие параметры нужно передать, чтобы получить то, что вы хотите. Я искренне рекомендую их обоих.
Для Python лучшим решением может быть IPy ( http://pypi.python.org/pypi/IPy/0.51 )
В Java вы можете использовать
InetAddress.getByName(IP)
, а затем проверять исключения, создаваемые этим для проверки IPv6-адресов.
Вы также можете использовать Sun Propreitary API, если вам это подходит. Это не будет выполнять поиск DNS. (Они могут изменить / удалить его без уведомления, поскольку это их собственный API. Это предупреждение, которое появится при компиляции кода с его использованием)
boolean sun.net.util.IPAddressUtil.isIPv6LiteralAddress(String IP)
Насколько я понимаю, вы должны использовать getaddrinfo ()
в системах, в которых он есть, то есть в Linux и POSIX. Нет необходимости писать собственный низкоуровневый синтаксический анализатор.
Windows также предоставляет getaddrinfo ()
в XP и более поздних версиях.
Жаль, что Python 3.1 потерял библиотеку ipaddr.
Она по-прежнему доступна как сторонняя библиотека: py-ipaddr , доступная на PyPI ].
>>> ipaddr.IPv6Address('0:0::0:1').compressed
'::1'
>>> ipaddr.IPv6Address('::ffff:123.45.67.89').ipv4_mapped
IPv4Address('123.45.67.89')
>>> ipaddr.IPv6Network('::ffff:123.45.67.89/128')
IPv6Network('::ffff:7b2d:4359/128')
getaddrinfo уже возвращает самую короткую текстовую форму, так что если у вас более длинная форма, вы можете канонизировать, снова запустив getaddrinfo. Пример Python,
import sys, socket;
result = socket.getaddrinfo('0:0::0:1', None);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];
Выводит следующее,
family:10 socktype:1 proto:6 canonname: sockaddr:('::1', 0, 0, 0)
Блоки CIDR IPv6 кажутся плохо документированными или определенными, поэтому я написал свою собственную реализацию inet6_network для работы с этим (C99).