Учитывая IP-адрес (скажем, 192.168.0.1), как мне проверить, находится ли он в сети (скажем, 192.168.0.0/24) в Python?
Есть ли в Python общие инструменты для манипулирования IP-адресами? Такие вещи, как поиск хоста, IP-адрес для int, сетевой адрес с сетевой маской для int и так далее? Надеюсь, в стандартной библиотеке Python для 2.5.
python
networking
ip-address
cidr
Staale
источник
источник
Ответы:
Эта статья показывает , что вы можете сделать это с
socket
иstruct
модулями без особых дополнительных усилий. Я немного добавил в статью следующее:Это выводит:
Если вам нужна только одна функция, которая принимает строки, это будет выглядеть так:
источник
return struct.unpack('<L',socket.inet_aton(ip))[0]
addressInNetwork('172.7.1.1', '172.3.0.0/16') -> True
(я преобразовал 'L' в '<L' в своей 64-битной ОС)addressInNetwork('172.7.1.1', '172.3.0.0/16') -> True
Мне нравится использовать для этого netaddr :
Как заметил arno_v в комментариях, новая версия netaddr делает это так:
источник
Используя ipaddress ( в stdlib начиная с 3.3 , в PyPi для 2.6 / 2.7 ):
Если вы хотите таким образом оценить множество IP-адресов, вы, вероятно, захотите заранее рассчитать сетевую маску, например
Затем для каждого адреса вычислите двоичное представление с одним из
Наконец, вы можете просто проверить:
источник
ipaddress.ip_address(u'192.168.0.1') in ipaddress.ip_network(u'192.168.0.0/24')
.__contains__
метод, чтобы сделать это эффективным способом, сравнивая целочисленные представления сетевых и широковещательных адресов, поэтому будьте уверены, если это было вашей проблемой .Для python3
Вывод :
источник
Этот код работает у меня на Linux x86. На самом деле я не задумывался о проблемах с порядком следования байтов, но я протестировал его с модулем «ipaddr», используя более 200 КБ IP-адресов, протестированных для 8 различных сетевых строк, и результаты ipaddr такие же, как и этот код.
Пример:
источник
Использование ipaddress Python3 :
Объяснение
Вы можете думать об IP-адресе как о сети с максимально возможной сетевой маской (
/32
для IPv4,/128
для IPv6)Проверка,
192.168.0.1
входит ли в сеть, по192.168.0.0/16
сути то же самое, что и проверка того,192.168.0.1/32
является ли подсеть192.168.0.0/16
источник
Я попробовал решение Дэйва Уэбба, но столкнулся с некоторыми проблемами:
Самое главное - совпадение должно быть проверено операцией AND IP-адреса с маской, а затем проверка результата, точно совпадающего с сетевым адресом. Не выполняйте операцию AND IP-адреса с сетевым адресом, как это было сделано.
Я также заметил, что простое игнорирование поведения порядка байтов при условии, что согласованность сохранит вас, будет работать только для масок на границах октетов (/ 24, / 16). Чтобы другие маски (/ 23, / 21) работали правильно, я добавил «больше» к командам структуры и изменил код для создания двоичной маски, чтобы он начинался со всех «1» и сдвигался влево на (32-маска ).
Наконец, я добавил простую проверку того, что сетевой адрес действителен для маски, и просто распечатал предупреждение, если это не так.
Вот результат:
источник
Я не любитель использовать модули, когда они не нужны. Эта работа требует только простых математических расчетов, поэтому вот моя простая функция:
Затем использовать:
Вот и все, это намного быстрее, чем приведенные выше решения с включенными модулями.
источник
{TypeError}'map' object is not subscriptable
. Вам нужноo = list(o)
послеo = map(int, ip.split('.'))
Нет в стандартной библиотеке для версии 2.5, но с помощью ipaddr это очень просто. Я считаю, что это в 3.3 под названием ipaddress.
источник
Принятый ответ не работает ... что меня злит. Маска обратная и не работает с любыми битами, кроме простого 8-битного блока (например, / 24). Я адаптировал ответ, и он отлично работает.
вот функция, которая возвращает двоичную строку с точками, чтобы помочь визуализировать маскировку ... вроде как
ipcalc
вывод.например:
источник
Код Марка почти правильный. Полная версия кода -
Очевидно, из тех же источников, что и выше ...
Очень важно отметить, что первый код имеет небольшую ошибку - IP-адрес 255.255.255.255 также отображается как действительный IP-адрес для любой подсети. У меня было уйма времени, чтобы заставить этот код работать, и спасибо Марку за правильный ответ.
источник
Использование модуля "struct" может вызвать проблемы с порядком байтов и размерами типов, и в этом нет необходимости. И socket.inet_aton () тоже. Python очень хорошо работает с IP-адресами, разделенными точками:
Мне нужно выполнить сопоставление IP-адресов для каждого вызова accept () для всего набора допустимых исходных сетей, поэтому я предварительно вычисляю маски и сети как целые числа:
Затем я могу быстро увидеть, находится ли данный IP-адрес в одной из этих сетей:
Импорт модулей не требуется, и код очень быстро соответствует.
источник
из netaddr импортировать all_matching_cidrs
Вот пример использования этого метода:
Обычно вы предоставляете IP-адрес в качестве первого аргумента и список cidr в качестве второго аргумента. Возвращается список совпадений.
источник
источник
netmask
значений. Я взял на себя смелость исправить это.в предыдущем решении есть ошибка в ip & net == net. Правильный поиск по IP-адресу: ip & netmask = net
исправленный код:
источник
В выбранном ответе есть ошибка.
Ниже приведен правильный код:
Примечание:
ipaddr & netmask == netaddr & netmask
вместоipaddr & netmask == netmask
.Я также заменяю
((2L<<int(bits)-1) - 1)
на((1L << int(bits)) - 1)
, поскольку последнее кажется более понятным.источник
((2L<<int(bits)-1) - 1)
правильным. например, если маска равна 16, она должна быть "255.255.0.0" или 65535L, но((1L << int(bits)) - 1)
получится 32767L, что неверно.((1L << int(bits)) - 1)
в моей системе выдает 65535L сbits
установленным значением 16 !!bits
установлено значение0
,((2L<<int(bits)-1) - 1)
возникает ошибка.Вот класс, который я написал для сопоставления самого длинного префикса:
А вот и тестовая программа:
источник
Спасибо за сценарий!
Я довольно долго работал над этим, чтобы все заработало ... Так что делюсь этим здесь
Функция makeMask не работает! Работает только для / 8, / 16, / 24
Ex:
Поэтому я использовал другую функцию calcDottedNetmask (mask) из http://code.activestate.com/recipes/576483-convert-subnetmask-from-cidr-notation-to-dotdecima/
Ex:
Пример: в настоящее время функция неправильная
Итак, моя новая функция addressInNetwork выглядит так:
А теперь ответ правильный !!
Я надеюсь, что это поможет другим людям, сэкономив им время!
источник
Что касается всего вышеперечисленного, я думаю, что socket.inet_aton () возвращает байты в сетевом порядке, поэтому правильный способ их распаковки, вероятно,
источник
$ python check-subnet.py
False
True
False
источник
>>> struct.unpack('!L',socket.inet_aton('10.10.10.110'))[0] 168430190 >>> socket.inet_ntoa(struct.pack('!L', 168430190)) '10.10.10.110'
Я ничего не знаю о стандартной библиотеке, но PySubnetTree - это библиотека Python, которая выполняет сопоставление подсетей.
источник
Из различных источников, приведенных выше, и из моих собственных исследований, вот как я получил подсеть и вычисление адресов. Этих кусочков достаточно, чтобы решить вопрос и другие связанные с ним вопросы.
источник
В Python есть API под названием SubnetTree, который отлично справляется с этой задачей. Это простой пример:
Это ссылка
источник
Вот мой код
источник
Если вы не хотите импортировать другие модули, вы можете использовать:
источник
Я попробовал одно подмножество предлагаемых решений в этих ответах ... безуспешно, я наконец адаптировал и исправил предложенный код и написал свою фиксированную функцию.
Я протестировал его и работает, по крайней мере, на архитектурах с прямым порядком байтов - egx86 - если кому-то нравится попробовать архитектуру с прямым порядком байтов, пожалуйста, дайте мне отзыв.
IP2Int
код взят из этого сообщения , другой метод - это полностью (для моих тестовых случаев) исправление предыдущих предложений в этом вопросе.Код:
Надеюсь пригодится,
источник
Вот решение с использованием пакета netaddr
источник