Шаг 207.
Python: сборник рецептов.
Сети и веб-программирование. Генерация диапазона IP-адресов из CIDR-адреса

    На этом шаге мы рассмотрим использование модуля ipaddress для решения указанной задачи.

Задача

    У вас есть сетевой CIDR-адрес типа 123.45.67.89/27, и вы хотите сгенерировать диапазон всех IP-адресов, которые он представляет (то есть 123.45.67.64, 123.45.67.65, ..., 123.45.67.95).

Решение

    Для выполнения таких вычислений удобно использовать модуль ipaddress. Например:

>>> import ipaddress
>>> net = ipaddress.ip_network('123.45.67.64/27')
>>> net
IPv4Network('123.45.67.64/27')
>>> for a in net:
	print(a)

	
123.45.67.64
123.45.67.65
123.45.67.66
123.45.67.67
123.45.67.68
123.45.67.69
123.45.67.70
123.45.67.71
123.45.67.72
123.45.67.73
123.45.67.74
123.45.67.75
123.45.67.76
123.45.67.77
123.45.67.78
123.45.67.79
123.45.67.80
123.45.67.81
123.45.67.82
123.45.67.83
123.45.67.84
123.45.67.85
123.45.67.86
123.45.67.87
123.45.67.88
123.45.67.89
123.45.67.90
123.45.67.91
123.45.67.92
123.45.67.93
123.45.67.94
123.45.67.95
>>> 
>>> net6 = ipaddress.ip_network('12:3456:78:90ab:cd:ef01:23:30/125')
>>> net6
IPv6Network('12:3456:78:90ab:cd:ef01:23:30/125')
>>> for a in net6:
	print(a)

	
12:3456:78:90ab:cd:ef01:23:30
12:3456:78:90ab:cd:ef01:23:31
12:3456:78:90ab:cd:ef01:23:32
12:3456:78:90ab:cd:ef01:23:33
12:3456:78:90ab:cd:ef01:23:34
12:3456:78:90ab:cd:ef01:23:35
12:3456:78:90ab:cd:ef01:23:36
12:3456:78:90ab:cd:ef01:23:37
>>> 

    Сетевые объекты также позволяют индексирование по принципу массивов. Например:

>>> net.num_addresses
32
>>> net[0]
IPv4Address('123.45.67.64')
>>> net[1]
IPv4Address('123.45.67.65')
>>> net[-1]
IPv4Address('123.45.67.95')
>>> net[-2]
IPv4Address('123.45.67.94')
>>> 

    Также вы можете выполнять такие операции, как проверка на принадлежность к сети:

>>> a = ipaddress.ip_address('123.45.67.69')
>>> a in net
True
>>> b = ipaddress.ip_address('123.45.67.123')
>>> b in net
False
>>> 

    IP-адрес и сетевой адрес могут быть определены вместе как IP-интерфейс. Например:

>>> inet = ipaddress.ip_interface('123.45.67.73/27')
>>> inet.network
IPv4Network('123.45.67.64/27')
>>> inet.ip
IPv4Address('123.45.67.73')
>>> 


Обсуждение

    Модуль ipaddress имеет классы для представления IP-адресов, сетей и интерфейсов. Это особенно полезно, если вы хотите написать код, который должен как-то манипулировать сетевыми адресами (парсинг, вывод, валидация и т. п.).

    Обратите внимание, что между модулем ipaddress и другими связанными с сетью модулями, такими как библиотека socket, есть лишь ограниченная связь. В частности, обычно невозможно использовать экземпляр IPv4Address в качестве замены строки с адресом. Вместо этого вы должны явно конвертировать его с помощью str(). Например:

>>> a = ipaddress.ip_address('127.0.0.1')
>>> from socket import socket, AF_INET, SOCK_STREAM
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.connect((a, 8080))
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    s.connect((a, 8080))
TypeError: str, bytes or bytearray expected, not IPv4Address
>>> s.connect((str(a), 8080))
>>> 

    См. "Введение в модуль ipaddress", чтобы получить больше информации и продвинутых примеров использования.

    На следующем шаге мы рассмотрим создание простого REST-интерфейса.




Предыдущий шаг Содержание