Задание 13 ЕГЭ по информатике на Python: IP-адрес и маска сети

опубликовано
читать
≈ 3 мин
автор
среда и версия
Python 3.14.2 в браузере (Pyodide 314.0.3) — там же, где запускаются примеры на странице; вывод совпал с CPython 3.14.7
содержание решать задачи Python для начинающих

В задании 13 ЕГЭ по информатике дают IP-адрес и маску сети и спрашивают об адресах этой сети: каков адрес самой сети, сколько в ней адресов с каким-то свойством, какой может быть маска. Руками это перевод октетов в двоичную запись и побитовое И, а на Python всё это умеет стандартный модуль ipaddress. В проекте ЕГЭ-2027 эта тема переходит в задание 10, а решение не меняется. Примеры ниже запускаются прямо на странице и составлены для этой статьи: на экзамене адреса будут другими, а шаблоны — те же.

ЕГЭ / 01

Адрес сети — это адрес И маска, бит за битом

Адрес сети — это адрес И маска, бит за битомУзел 172.31.150.77, маска 255.255.240.0. Там, где в маске 255, октет адреса остаётся: 172 и 31. Где в маске 0, октет обнуляется: 77 становится 0. Третий октет считают побитово: 150 — это 1001 0110, 240 — 1111 0000, побитовое И даёт 1001 0000, то есть 144. Адрес сети — 172.31.144.0.1 · по октетам2 · третий октет в двоичной записиадрес1723115077маска2552552400сеть1723114401501001 01102401111 00001441001 0000где в маске 255, октет адреса остаётся, где 0 — обнуляетсяграничный октет — побитовое И: 150 & 240 = 144, адрес сети 172.31.144.0
Маска оставляет биты адреса там, где у неё единицы. ip_network делает это сам, а 150 & 240 — тот же расчёт для одного октета вручную.

Пример задачи: адреса сети с условием

Сеть задана IP-адресом 10.40.17.200 и маской 255.255.255.224. Сколько адресов этой сети, включая адрес сети и широковещательный адрес, содержат в двоичной записи чётное число единиц?

from ipaddress import ip_network

net = ip_network('10.40.17.200/255.255.255.224', strict=False)
print(net, net.num_addresses)
count = 0
for ip in net:
    if bin(int(ip)).count('1') % 2 == 0:
        count += 1
print(count)
10.40.17.192/27 32
16
  • ip_network принимает адрес и маску через косую черту. strict=False нужен потому, что 10.40.17.200 — адрес узла, а не сети: без этого флага Python остановится с ошибкой.
  • print(net) показывает адрес сети и длину маски: /27 — это 27 единиц в маске, и в сети 2⁵ = 32 адреса.
  • for ip in net перебирает все адреса сети по порядку — от адреса сети до широковещательного.
  • int(ip) превращает адрес в 32-битное число, а bin(...).count('1') считает единицы сразу во всех четырёх октетах.

Ответ: 16.

Адрес сети

Адрес сети — побитовое И адреса и маски (схема выше). Узел 172.31.150.77, маска 255.255.240.0:

from ipaddress import ip_network

net = ip_network('172.31.150.77/255.255.240.0', strict=False)
print(net.network_address, net.prefixlen)
print(150 & 240)
print(sum(int(part) for part in str(net.network_address).split('.')))
172.31.144.0 20
144
347
  • net.network_address — адрес сети, net.prefixlen — число единиц в маске.
  • 150 & 240 — тот же расчёт для третьего октета вручную: & — побитовое И.
  • Последняя строка складывает октеты адреса сети. По данным о проекте ЕГЭ-2027, в задании 10 ответ про адрес сети будут записывать именно так — суммой октетов, а не адресом без точек.

Наибольшая маска для двух узлов

Узлы с адресами 118.95.130.40 и 118.95.201.40 находятся в одной сети. Какое наибольшее число единиц может быть в маске этой сети?

from ipaddress import ip_address, ip_network

a = ip_address('118.95.130.40')
b = ip_address('118.95.201.40')
best = 0
for p in range(33):
    net = ip_network(f'{a}/{p}', strict=False)
    edges = (net.network_address, net.broadcast_address)
    if b in net and a not in edges and b not in edges:
        best = p
print(best, ip_network(f'{a}/{best}', strict=False).netmask)
17 255.255.128.0
  • Перебирается длина маски p от 0 до 32: сеть строится по первому узлу, и проверяется, лежит ли в ней второй.
  • Узел не может совпадать с адресом сети или широковещательным адресом — это проверяет edges.
  • best перезаписывается при каждом подходящем p, поэтому в конце остаётся наибольшее.

Проверка руками. Первые два октета совпадают. В третьем 130 = 1000 0010, а 201 = 1100 1001: совпадает только первый бит. Общих бит 8 + 8 + 1 = 17, значит, и единиц в маске не больше 17.

Ответ: 17.

Частые ошибки

Нет strict=False. ip_network('10.40.17.200/27') останавливается с ошибкой ValueError: 10.40.17.200/27 has host bits set: модуль ждёт адрес сети, а получил адрес узла.

hosts() вместо самой сети. net.hosts() пропускает адрес сети и широковещательный адрес, и в первом примере вышло бы 15 вместо 16. Перебирай то, о чём спрашивает условие: «адреса узлов» — hosts(), «все адреса сети» — саму сеть.

Единицы в десятичной записи. str(ip).count('1') считает символ «1» в записи вроде 10.40.17.200, а не единицы двоичной записи. В первом примере так вышло бы 13 вместо 16.

bin от адреса. bin(ip) без int останавливается с ошибкой TypeError: 'IPv4Address' object cannot be interpreted as an integer — сначала адрес переводят в число.

Какие ещё задания решают программой — в статье «Python для ЕГЭ по информатике», двоичная запись и счёт единиц — в статье «Задание 5 ЕГЭ на Python». Свой вариант удобно проверять в песочнице Python: там можно вывести все адреса сети и их двоичную запись.

Источники