Адрес IPv4 — это 32-битное число
Привычная запись с точками — это просто четыре байта, записанные в десятичном виде. 192.168.1.1 — это байты C0 A8 01 01, которые, прочитанные как одно 32-битное число в порядке big-endian, дают 0xC0A80101 = 3 232 235 777. Каждый октет умножается на степень числа 256: 192×256³ + 168×256² + 1×256 + 1.
- Возьмите октеты по порядку: a, b, c, d.
- Вычислите a×16 777 216 + b×65 536 + c×256 + d.
- Для обратного преобразования последовательно делите на 256 и сохраняйте остатки (или сдвигайте вправо на 8 и накладывайте маску 255).
Где используется целочисленная форма
- Базы данных:
INET_ATON()/INET_NTOA()в MySQL и типinetв PostgreSQL хранят и индексируют адреса как числа, чтобы запросы по диапазону (ip BETWEEN start AND end) выполнялись быстро. Таблицы GeoIP используют тот же приём. - Программирование:
inet_atonв C,ip2longв PHP,int(ipaddress.ip_address(x))в Python,binary.BigEndian.Uint32(ip.To4())в Go. - Списки доступа и межсетевые экраны, которые сравнивают число с маской.
Необычные формы, которые принимают браузеры
Поскольку адрес — это число, http://3232235777/ и http://0xC0A80101/ в большинстве браузеров ведут на 192.168.1.1, а 192.168.257 разбирается как 192.168.1.1 (последняя часть переполняется в предыдущий октет). Это классический способ спрятать адрес в фишинговой ссылке и одна из причин строго проверять ввод, как делает этот инструмент.
Вопросы
Чему равен 192.168.1.1 как целое число?
3 232 235 777 в десятичном виде, 0xC0A80101 в шестнадцатеричном. Получается из 192×256³ + 168×256² + 1×256 + 1.
Зачем хранить IP-адреса как целые числа?
Целое число занимает 4 байта вместо до 15 символов, сортируется в сетевом порядке и позволяет проверить принадлежность к диапазону двумя сравнениями. Большинство данных GeoIP и межсетевых экранов хранится именно так.
Какое наибольшее целое число для IPv4?
4 294 967 295 (2³² − 1), то есть 255.255.255.255.
Работает ли это для IPv6?
Адреса IPv6 — это 128-битные числа, и для них нужен другой инструмент: используйте калькулятор IPv6, который показывает развёрнутую, сжатую и двоичную формы.
Совпадает ли 192.168.001.001 с 192.168.1.1?
Не гарантированно. Некоторые парсеры считают октет с ведущим нулём восьмеричным (001 ещё безобидно, но 010 дало бы 8). Записывайте октеты без ведущих нулей, чтобы избежать двусмысленности; этот инструмент отклоняет их именно по этой причине.