How to generate an IP range list in Python?
Here’s a short Python snippet that generates a list of IP addresses based on IP range. Nothing fancy, but could come in handy if you ever need it somewhere in your code. Enjoy!
def ipRange(start_ip, end_ip): start = list(map(int, start_ip.split("."))) end = list(map(int, end_ip.split("."))) temp = start ip_range = [] ip_range.append(start_ip) while temp != end: start[3] += 1 for i in (3, 2, 1): if temp[i] == 256: temp[i] = 0 temp[i-1] += 1 ip_range.append(".".join(map(str, temp))) return ip_range # sample usage ip_range = ipRange("192.168.1.0", "192.171.3.25") for ip in ip_range: print(ip)
Модуль ipaddress
Получим внешний IP -адрес нашего компьютера для работы с ним в командной строке. В Linux это делается так:
Последние 8 бит в 192.4.2.12 маскируются нулем и игнорируются при сравнении.
Любое целое число от 0 до 32 является допустимым, но такой вариант встречается реже:
К счастью, IPv4Network расчеты подсетей поддерживаются встроенным методом subnets() :
Случайным образом выберем адрес – 10.243.156.214 . Относится ли этот адрес к приватным? Для этого проверим, попадает ли он в диапазон cети 10.0.0.0/8 :
Продемонстрируем силу ._ip путем расширения класса IPv4Address :
from ipaddress import IPv4Address class MyIPv4(IPv4Address): def __and__(self, other: IPv4Address): if not isinstance(other, (int, IPv4Address)): raise NotImplementedError return self.__class__(int(self) & int(other))
Добавление .__and__() позволяет использовать бинарный оператор & , чтобы применять маску к IP-адресу:
>>> addr = MyIPv4("100.127.40.32") >>> mask = MyIPv4("255.192.0.0") # Соответствует префиксу /10 >>> addr & mask MyIPv4('100.64.0.0') >>> addr & 0xffc00000 # hex-литерал для 255.192.0.0 MyIPv4('100.64.0.0')
Метод __and__() позволяет использовать либо другой IPv4Address, либо непосредственно int в качестве маски. Поскольку MyIPv4 является подклассом IPv4Address, проверка isinstance() в данном случае вернет T rue .
Помимо перегрузки оператора, есть возможность добавить новые свойства:
import re from ipaddress import IPv4Address class MyIPv4(IPv4Address): @property def binary_repr(self, sep=".") -> str: """Представляет IPv4 в виде 4 блоков по 8 бит.""" return sep.join(f"" for i in self.packed) # 8 строка @classmethod def from_binary_repr(cls, binary_repr: str): """Создает IPv4 из двоичного представления.""" i = int(re.sub(r"[^01]", "", binary_repr), 2) # 14 строка return cls(i)
В методе binary_repr (строка 8), используется .packed для преобразования IP-адреса в массив байтов, который затем форматируется, как строковое представление бинарной формы.
В from _ binary _ repr , вызов int ( re . sub ( r «[^01]», «», binary _ repr ), 2) (строка 14) состоит из двух частей:
- удаление из входящей строки всего, кроме нулей и единиц;
- анализ результата с помощью int(, 2) .
Методы binary_repr() и from_binary_repr() позволяют проводить двустороннюю конвертацию:
>>> MyIPv4("220.14.9.37").binary_repr '11011100.00001110.00001001.00100101' >>> MyIPv4("255.255.0.0").binary_repr # Маска для префикса /16 '11111111.11111111.00000000.00000000' >>> MyIPv4.from_binary_repr("11011100 00001110 00001001 00100101") MyIPv4('220.14.9.37')
Таким образом, мы разобрали несколько способов использования преимуществ шаблона IP-as-integer, который может помочь расширить функциональность IPv4Address с небольшим количеством дополнительного кода.
Заключение
Если вам нравится язык Python и вы хотите детально овладеть стандартной библиотекой, у нас есть множество родственных публикаций: