Курс№10. IP-адреса и маски сети0%
Теория · номер 10 из 27

IP-адреса и маски сети

Даны IP-адрес и маска, надо найти адрес сети, широковещательный адрес или посчитать адреса с условием. В Python для этого есть готовый модуль, поэтому код получается короткий.

9 разделов~40 минут1 первичный балл
  1. 1Что проверяет номер
  2. 2Адрес и маска: минимум теории
  3. 3База: модуль ipaddress
  4. 4Адрес сети и наибольший адрес
  5. 5Условие на двоичную запись
  6. 6Ищем маску
  7. 7Узлы сети
  8. 8Ловушки перед экзаменом
  9. 9Домашка
Раздел 1 из 9

Что проверяет номер

Есть IP-адрес и маска сети. Это не сети как предмет, а арифметика с 32-разрядными числами. На настоящих экзаменах чаще всего встречаются два вида вопросов.

Найти адрес

Адрес сети, широковещательный адрес или наибольший адрес компьютера. Ответ это сумма чисел адреса или адрес без точек.

Узел 185.249.55.138, маска 255.255.192.0. Найдите широковещательный адрес, в ответе сумма его чисел.

Посчитать адреса

Перебираем адреса сети и считаем те, что подходят под условие на двоичную запись.

Сеть 172.16.160.0, маска 255.255.240.0. Сколько адресов, у которых количество единиц кратно 2?

Ещё встречаются задачи, где маску надо найти: по адресу узла и адресу сети или по двум узлам. Всё это решается кодом, руками будем только проверять маленькие примеры.

Ответы к примерам

Широковещательный адрес 185.249.63.255, сумма его чисел 752. Адресов с чётным числом единиц 2048.

Раздел 2 из 9

Адрес и маска: минимум теории

Адреса одной сети отличаются только в той части, где у маски нули. Если нулей k, адресов в сети 2^k. Первый из них это адрес сети, последний широковещательный, и компьютеру их назначить нельзя. Поэтому:

Слово в условииСколько их
«адресов»2^k
«узлов», «компьютеров», «хостов»2^k − 2

В маске могут стоять только числа 0, 128, 192, 224, 240, 248, 252, 254, 255. Других нет, потому что единицы идут подряд.

Разберём руками адрес 192.168.52.77 и маску 255.255.240.0. Первые два числа маски 255, там адрес не меняется. Последнее число маски 0, там получится 0. Интересен только третий байт:

52 в адресе00110100
240 в маске11110000
Поразрядное И00110000, это 48

Адрес сети 192.168.48.0. Нулей в маске 12, поэтому адресов 4096, а компьютеров 4094.

Раздел 3 из 9

База: модуль ipaddress

ip_network создаёт сеть и сразу знает всё, что мы считали руками.

python
from ipaddress import ip_network

# второй аргумент False (strict=False) разрешает дать адрес узла, а не сети
net = ip_network('192.168.52.77/255.255.240.0', False)

print(net.network_address)     # адрес сети
print(net.netmask)             # маска
print(net.broadcast_address)   # широковещательный адрес
print(net.num_addresses)       # сколько адресов всего
print(len(list(net.hosts())))  # сколько узлов (без адреса сети и широковещательного)

Числа те же, что в разделе 2. Маску можно писать точками (/255.255.240.0) или числом единиц (/20), результат будет один. Когда маску ищем перебором, удобно число: f'{адрес}/{m}'.

Ловушка

Без False запись ip_network('1.2.3.77/24') падает с ошибкой has host bits set. Если в условии дан адрес узла, а не сети, всегда пиши False.

Сеть можно перебирать циклом, а адрес записать в двоичной системе:

python
from ipaddress import ip_address

ip = ip_address('10.0.0.1')
print(f'{ip:b}')                       # 32 разряда
print(bin(int(ip))[2:])                # ведущие нули пропали
print(bin(int(ip))[2:].zfill(32))      # вернули 32 разряда

Запись f'{ip:b}' сразу даёт ровно 32 разряда с нулями слева. Её и используй. Для bin нули пришлось бы возвращать через .zfill(32), иначе количество нулей посчитается неверно.

Попробуй самучебная задача

Даны адрес узла 172.30.99.201 и маска 255.255.240.0. Найди адрес сети и сложи его четыре числа.

Попробуй самучебная задача

Маска сети 255.255.248.0. Сколько компьютеров может быть в такой сети?

Раздел 4 из 9

Адрес сети и наибольший адрес

В настоящих условиях всегда есть длинное вступление с определениями: что такое маска, адрес сети и широковещательный адрес. Его можно читать бегло, важен вопрос в конце. Вопросов три:

Ответ почти всегда записывается в одном из двух форматов: сумма четырёх чисел адреса («100.20.3.4» даёт 127) или адрес без точек («111.22.3.44» даёт 11122344).

python
from ipaddress import ip_network

net = ip_network('185.249.55.138/255.255.192.0', False)

print(net.network_address)                 # адрес сети
print(net.broadcast_address)               # широковещательный
print(net.broadcast_address - 1)           # наибольший адрес для компьютера

ip = net.broadcast_address
print(sum(ip.packed))                      # сумма октетов (packed это 4 байта адреса)
print(str(ip).replace('.', ''))            # адрес без разделителей

ip.packed отдаёт четыре байта адреса, а sum их складывает. Адрес минус единица работает прямо в Python. Наименьший адрес для компьютера это net.network_address + 1.

Попробуй самучебная задача

Сеть задана адресом узла 77.81.143.20 и маской 255.255.248.0. Найди наибольший адрес, который можно назначить компьютеру. В ответе запиши сумму его чисел.

Раздел 5 из 9

Условие на двоичную запись

Условия бывают такие: чётное число единиц, единиц больше, чем нулей, ровно k единиц. Цикл по net выдаёт все адреса сети по порядку, остаётся посчитать подходящие.

python
from ipaddress import ip_network

net = ip_network('192.168.10.64/255.255.255.224')
k = 0
for ip in net:                       # все адреса сети по порядку
    b = f'{ip:b}'                    # двоичная запись, сразу 32 разряда
    if b.count('1') % 2 == 0:        # чётное число единиц
        k += 1
print(k)

Если вопрос про компьютеры, а не про адреса, перебирай net.hosts() вместо net.

Если спрашивают наибольшее или наименьшее число единиц, цикл не нужен:

python
from ipaddress import ip_network

net = ip_network('11.45.96.0/255.255.240.0')
print(max(f'{ip:b}'.count('1') for ip in net))
print(min(f'{ip:b}'.count('1') for ip in net))

Неизвестное число A в адресе

Бывает, что в адресе сети стоит неизвестный байт A, и надо найти наименьшее A, при котором условие верно для всех адресов сети. Функция all проверяет как раз это: истинно ли условие для каждого адреса.

python
from ipaddress import ip_network

for A in range(0, 256):
    net = ip_network(f'172.16.{A}.0/255.255.255.240')
    if all(f'{ip:b}'.count('1') >= 11 for ip in net):
        print(A)
        break

Если нужно число подходящих значений A, убери break и считай k += 1.

Попробуй самучебная задача

Сеть задана адресом 10.4.16.0 и маской 255.255.252.0. Сколько в ней адресов, в двоичной записи которых ровно 8 единиц?

Раздел 6 из 9

Ищем маску

Тут маска неизвестна. Масок всего 33, от /0 до /32, поэтому просто перебираем число единиц m.

Маска по узлу и адресу сети

python
from ipaddress import ip_network

for m in range(0, 33):
    net = ip_network(f'192.168.52.77/{m}', False)
    if str(net.network_address) == '192.168.48.0':   # адрес сети из условия
        print(m, net.netmask)

Подходят /20 и /21. Если спрашивают наибольшее значение третьего байта маски, ответ 248. Нужный байт можно достать так: str(net.netmask).split('.')[2].

Руками: 52 это 00110100, а 48 это 00110000. Маска должна сохранить первые четыре разряда и обнулить единицу в хвосте. 11110000 (240) это делает, 11111000 (248) тоже, а 11111100 (252) единицу уже оставит.

Если просят не байт, а количество подходящих масок, цикл тот же, только в if стоит счётчик.

Два узла

Если при какой-то маске два узла в одной сети, то и при всех более коротких масках они тоже в одной сети. Поэтому:

python
from ipaddress import ip_network

a, b = '10.20.133.17', '10.20.141.200'
for m in range(0, 33):
    n1 = ip_network(f'{a}/{m}', False)
    n2 = ip_network(f'{b}/{m}', False)
    if n1 == n2:
        last_same = m          # запоминаем, ответ будет последним
print(last_same)
Попробуй самучебная задача

Узел с адресом 130.44.201.7 находится в сети с адресом 130.44.192.0. Чему равно наибольшее возможное значение третьего слева байта маски?

Попробуй самучебная задача

Узлы с адресами 10.1.66.5 и 10.1.70.9 находятся в разных сетях. Каково наименьшее возможное количество единиц в маске?

Раздел 7 из 9

Узлы сети

Узлы нумеруются с 1 по порядку, а hosts() отдаёт их без адреса сети. Превращаем в список и берём нужный. Индексы в списке начинаются с 0, поэтому 300-й узел это hosts[299].

python
from ipaddress import ip_network

net = ip_network('10.7.64.0/255.255.252.0')
hosts = list(net.hosts())      # превратили в список
print(hosts[299])              # 300-й узел: индекс на 1 меньше

Если спрашивают только количество, адрес можно взять любой, важна только маска:

python
from ipaddress import ip_network

net = ip_network('0.0.0.0/255.255.254.0')
print(net.num_addresses)             # адресов
print(len(list(net.hosts())))        # узлов (на 2 меньше)

Руками: 254 это 11111110, один нуль, и ещё 8 нулей в последнем байте. Всего 9 нулей, адресов 2^9 = 512, узлов 510.

Попробуй самучебная задача

Сеть задана адресом 192.168.16.0 и маской 255.255.252.0. Узлы нумеруются по порядку, начиная с 1. Чему равен последний байт адреса узла с номером 500?

Раздел 8 из 9

Ловушки перед экзаменом

ЛовушкаКак не попасться
Адреса и узлыАдресов 2^k, это num_addresses. Узлов 2^k − 2, это hosts()
Ошибка has host bits setДля адреса узла всегда пиши False
Наибольший адрес компьютераЭто широковещательный минус 1, а не сам широковещательный
Нули в записи bin(int(ip))Бери f'{ip:b}', там всегда 32 разряда
Сравнение адреса с текстомnetwork_address и netmask не строки, оборачивай в str(...)
Номер узла и индекс300-й узел это hosts[299]
Перебор адресов очень большой сетиВ сети /8 их 16 миллионов, на сайте код упрётся в лимит 10 секунд. Когда ищешь маску, адреса перебирать не надо, хватит network_address
«Наименьшая маска» и «наименьший байт»Читай, что именно просят: число единиц или значение байта
Формат ответаСумма чисел или адрес без точек: смотри пример в конце условия

Как решать задачу

  1. Определи, что дано (узел, сеть, маска) и что просят (адрес, маска, количество).
  2. Найди слово: «адресов» или «узлов».
  3. Пиши цикл по m, если ищешь маску, и цикл по net, если считаешь адреса.
  4. Сомневаешься в коде? Проверь его на маленькой сети: /30 даёт 4 адреса и 2 узла.
  5. Запиши ответ в формате из условия.
Раздел 9 из 9

Домашка

Семь задач с настоящих экзаменов и из банка ФИПИ. Решай прямо здесь: кнопка «Решать здесь» открывает редактор, а код каждой задачи сохраняется.

Перед тем как писать код, ответь себе на три вопроса по условию:

Где теряют балл в этих задачах

В задачах про компьютер не забудь вычесть 1 из широковещательного адреса. В шестой задаче ответ это адрес без точек, а не сумма. В седьмой считаем все адреса сети, поэтому цикл идёт по net, а не по hosts().

Ещё задачи этого вида и учебные задачи на поиск маски лежат в разделе «Задания», №10.

В проекте ЕГЭ-2027 эта тема стоит под №10, в ЕГЭ-2026 это был №13. Утверждённая демоверсия 2027 выйдет в ноябре, типы задач могут уточниться. Примеры и задачи «Попробуй сам» учебные, в домашке задачи с настоящих экзаменов и из банка ФИПИ.