Мне нужно заблокировать некоторые IP-адреса из некоторых стран, но мне предоставляется только начальный IP-адрес и конечный IP-адрес:
11.22.33.44 - 11.22.35.200
Я хотел бы рассчитать подсеть, чтобы он выглядел так:
(not accurate)
11.22.33.44/14
Как определить подсеть, заданную диапазоном IP-адресов в Python?
В последнее время я не тратил много времени, но вот, как я думаю, вы можете сделать это наиболее эффективно.
Прежде всего, важно признать, что не все диапазоны IP могут быть представлены как одна подсеть. Давайте взглянем на общую подсеть, такую как
192.168.0.0/24
Параметр /24
указывает, что первые 24 бита 192.168.0.0
дают сетевой префикс, в этом случае 192.168.0
и остальные биты используются для адресации хоста. Вы получаете диапазон от 192.168.0.0
до 192.168.0.255
.
ipcalc
может помочь нам здесь. Посмотрим, согласен ли он:
$ ipcalc 192.168.0.0 - 192.168.0.255
deaggregate 192.168.0.0 - 192.168.0.255
192.168.0.0/24
Все идет нормально. Но что, если вы хотите исключить .0
или .255
, который используется для трансляции? Существует не одна подсеть, которая представляет этот диапазон:
$ ipcalc 192.168.0.0 - 192.168.0.254
deaggregate 192.168.0.0 - 192.168.0.254
192.168.0.0/25
192.168.0.128/26
192.168.0.192/27
192.168.0.224/28
192.168.0.240/29
192.168.0.248/30
192.168.0.252/31
192.168.0.254/32
Подсети растут силами двух, и когда наш диапазон не проникает в эту структуру, мы в конечном итоге оказываемся в таких вещах.
Пример, который вы дали, кстати, не дает ни одной подсети:
$ ipcalc 11.22.33.44 - 11.22.35.200
deaggregate 11.22.33.44 - 11.22.35.200
11.22.33.44/30
11.22.33.48/28
11.22.33.64/26
11.22.33.128/25
11.22.34.0/24
11.22.35.0/25
11.22.35.128/26
11.22.35.192/29
11.22.35.200/32
Python имеет модуль ipaddress
. Посмотрим, согласуется ли его функция ipcalc
( summarize_address_range()
с ipcalc
(отформатирована для удобочитаемости):
>>> import ipaddress
>>> list(ipaddress.summarize_address_range(
ipaddress.IPv4Address('192.168.0.0'),
ipaddress.IPv4Address('192.168.0.255')))
[IPv4Network('192.168.0.0/24')]
Все идет нормально. Как насчет второго примера?
>>> list(ipaddress.summarize_address_range(
ipaddress.IPv4Address('11.22.33.44'),
ipaddress.IPv4Address('11.22.35.200')))
[IPv4Network('11.22.33.44/30'),
IPv4Network('11.22.33.48/28'),
IPv4Network('11.22.33.64/26'),
IPv4Network('11.22.33.128/25'),
IPv4Network('11.22.34.0/24'),
IPv4Network('11.22.35.0/25'),
IPv4Network('11.22.35.128/26'),
IPv4Network('11.22.35.192/29'),
IPv4Network('11.22.35.200/32')]
Похоже на матч.