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

Задание 13 ЕГЭ по информатике повышенного уровня (3 минуты на выполнение) проверяет умение работать с масками подсети и IP-адресами. IP-адрес — 32-битное число, записываемое в виде четырёх чисел, разделённых точками (диапазон каждого числа от 0 до 255). Маску можно представить как количество единиц в 32-битном числе.

Использование модуля ipaddress

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

import ipaddress

В дальнейшем будем использовать функции этого модуля без указания имени модуля перед именем функции (благодаря импорту *).

Примеры решения задач

Рассмотрим примеры решения задач 13-го задания.

Задача 1

  • Условие: Для узла с IP-адресом 111.81.208.27 адрес сети равен 111.81.192.0. Чему равно наименьшее возможное значение третьего слева байта маски? Ответ запишите в виде десятичного числа.
  • Решение: Так как маска представляется количеством единиц, переберём их в цикле от меньшего к большему:
for m in range(33):
    net = ipaddress.ip_network(f'111.81.208.27/{m}', strict=False)
    if str(net.network_address) == '111.81.192.0':
        print(net.netmask.packed)
        break

Программа выведет маску. Третий слева байт маски — 192. Ответ: 192.

Задача 2

  • Условие: Для узла с IP-адресом 229.117.114.172 адрес сети равен 229.117.112.0. Каково наименьшее возможное количество единиц в двоичной записи маски?
  • Решение: Аналогично задаче 1, перебираем количество единиц и проверяем адрес сети:
for m in range(33):
    net = ipaddress.ip_network(f'229.117.114.172/{m}', strict=False)
    if str(net.network_address) == '229.117.112.0':
        print(m)
        break

Программа выведет наименьшее количество единиц в маске.

Задача 3

  • Условие: Два узла находятся в одной сети: 215.171.155.54 и 215.137.155.118. Укажите наибольшее возможное значение третьего слева байта маски этой сети.
  • Решение: Перебираем маски от 32 до 0, создавая сети по первому и второму IP-адресам. Если сети совпадают, выводим маску:
for m in range(32, -1, -1):
    net1 = ipaddress.ip_network(f'215.171.155.54/{m}', strict=False)
    net2 = ipaddress.ip_network(f'215.137.155.118/{m}', strict=False)
    if net1 == net2:
        print(net1.netmask.packed)
        break

Третий байт маски — 240. Ответ: 240.

Задача 4

  • Условие: Узлы с IP-адресами 161.137.235.210 и 161.137.150.118 находятся в разных сетях. Укажите наименьшее возможное значение третьего слева байта маски этих сетей.
  • Решение: Аналогично задаче 3, но условие — сети должны быть разными:
for m in range(33):
    net1 = ipaddress.ip_network(f'161.137.235.210/{m}', strict=False)
    net2 = ipaddress.ip_network(f'161.137.150.118/{m}', strict=False)
    if net1 != net2:
        print(net1.netmask.packed)
        break

Третий байт маски — 192. Ответ: 192.

Задача 5

  • Условие: Сеть задана IP-адресом 172.16.128.0 и маской 255.255.192.0. Сколько в этой сети IP-адресов, для которых сумма единиц в двоичной записи не кратна двум?
  • Решение: Создаём сеть, перебираем IP-адреса и проверяем условие:
net = ipaddress.ip_network('172.16.128.0/18')
count = 0
for ip in net:
    binary = bin(int(str(ip))).count('1')
    if binary % 2 != 0:
        count += 1
print(count)

Задача 6

  • Условие: Сеть задана IP-адресом 202.75.38.152 и маской 255.255.255.248. Сколько в этой сети IP-адресов, у которых в двоичной записи есть сочетание трёх подряд идущих единиц?
  • Решение: Создаём сеть, перебираем IP-адреса и проверяем наличие подстроки ‘111’ в двоичной записи:
net = ipaddress.ip_network('202.75.38.152/28')
count = 0
for ip in net:
    binary = bin(int(str(ip)))[2:]
    if '111' in binary:
        count += 1
print(count)

Задача 7

  • Условие: Сеть задана IP-адресом 94.253.120.80 и маской 255.255.128.0. Сколько в этой сети IP-адресов, для которых количество единиц в двоичной записи не кратно шести, и двоичная запись оканчивается на «101»?
  • Решение:
net = ipaddress.ip_network('94.253.120.80/17')
count = 0
for ip in net:
    binary = bin(int(str(ip)))[2:].zfill(32)
    if (binary.count('1') % 6 != 0) and binary.endswith('101'):
        count += 1
print(count)

Важно: Функция bin() удаляет ведущие нули. Для корректного подсчёта и проверки окончания, необходимо использовать zfill(32) для дополнения двоичной строки до 32 бит.

Задача 8

  • Условие: Узлы с IP-адресами 193.45.192.104 и 193.45.206.210 находятся в одной сети. Укажите наименьшее возможное количество принадлежащих этой сети IP-адресов, в двоичной записи которых чётное число единиц.
  • Решение: Перебираем маски, проверяем принадлежность обоих узлов к сети и считаем IP-адреса с чётным числом единиц:
for m in range(32, -1, -1):
    net = ipaddress.ip_network(f'193.45.192.104/{m}', strict=False)
    if ipaddress.ip_address('193.45.206.210') in net:
        count = sum(1 for ip in net if bin(int(str(ip))).count('1') % 2 == 0)
        print(count)
        break

Модуль ipaddress значительно упрощает решение задач на работу с IP-адресами и масками подсетей. Важно понимать логику работы с масками и уметь перебирать возможные варианты для нахождения решения. Обратите внимание на особенности работы с двоичным представлением IP-адресов и корректную обработку ведущих нулей.

Что будем искать? Например,программа