Задание 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-адресов и корректную обработку ведущих нулей.