К содержанию

Подтема 5 из 6

Адреса с условием на двоичную запись

Как считать адреса с условием на двоичную запись: число единиц, чётность, часть адреса.

Фиксированные биты

Сколько адресов сети задачи темы содержат в двоичной записи ровно 12 единиц?

Сетевые биты одинаковы у всех адресов сети: их единицы считают один раз, а меняются только свободные биты. В сетевой части нашей сети 172 = 10101100 — 4 единицы, 20 = 00010100 — 2, сетевые биты третьего октета 010011 — 3. Всего 9 единиц у каждого адреса.

Сеть 172.20.76.0/22: 22 фиксированных бита дают каждому адресу одни и те же 9 единиц, а десять свободных битов (знаки вопроса) меняются от адреса к адресу.

Значит, для 12 единиц в десяти свободных битах нужно ровно 3 единицы. Посчитать такие адреса проще всего перебором сети: цикл for address in net выдаёт все её адреса по порядку, включая оба края, а count('1') () считает единицы:

from ipaddress import ip_networknet = ip_network('172.20.77.140/22', strict=False)count = 0for address in net:    if f'{address:b}'.count('1') == 12:        count += 1print(count)
120

Число 120 — это число способов выбрать 3 позиции из 10; как его посчитать без перебора, разбирает дополнительный урок. Важно: 22 сетевых бита не значат 22 единицы — среди фиксированных битов есть и нули.

Чётность и кратность

Если считают только адреса компьютеров, каждый из двух специальных адресов проверяют по условию — вычитать два автоматически нельзя. В нашей сети адрес сети содержит 9 единиц — число, кратное 3, а широковещательный — 9 + 10 = 19, не кратное. Адресов с числом единиц, кратным 3, всего 341; среди адресов компьютеров — на один меньше, а не на два. Перебор только адресов компьютеров даёт net.hosts():

from ipaddress import ip_networknet = ip_network('172.20.77.140/22', strict=False)every = [a for a in net if f'{a:b}'.count('1') % 3 == 0]hosts = [a for a in net.hosts() if f'{a:b}'.count('1') % 3 == 0]print(len(every), len(hosts))print(f'{net.network_address:b}'.count('1'))
341 340 9

Кратность проверяют остатком (): «кратно 3» — % 3 == 0, «чётно» — % 2 == 0. Для чётности есть короткое рассуждение: при хотя бы одном свободном бите ровно половина адресов имеет чётное число единиц — в нашей сети 512 из 1024.

Обоснование · необязательноПочему ровно половина

Разобьём варианты свободных битов на пары, отличающиеся только последним битом: в паре число единиц k и k + 1, одно чётное, другое нет. На маленькой сети с четырьмя свободными битами и семью единицами в сетевой части:

Все 16 вариантов четырёх свободных битов парами, отличающимися последним битом. Рядом — число единиц всего адреса (7 фиксированных плюс свободные): в каждой паре одно чётное и одно нечётное, всего 8 чётных.

Не путай чётность адреса и чётность числа единиц: 3 = 11₂ — число нечётное, а единиц в нём две.

Часть адреса

Условие на часть адреса проверяют на части строки из 32 битов — срезе. bits[:16] — первые два октета, bits[16:] — последние два, bits[16:24] — третий октет. Выбери условие, чтобы увидеть проверку:

ровно 12 единиц
bits.count('1') == 12
число единиц кратно 3
bits.count('1') % 3 == 0
нулей больше, чем единиц
bits.count('0') > bits.count('1')
две последние цифры 11
bits[-2:] == '11'
в третьем октете единиц столько же, сколько нулей
bits[16:24].count('1') == bits[16:24].count('0')

Например, в скольких адресах нашей сети в первых двух октетах единиц больше, чем в последних двух?

from ipaddress import ip_networknet = ip_network('172.20.77.140/22', strict=False)count = 0for address in net:    bits = f'{address:b}'    if bits[:16].count('1') > bits[16:].count('1'):        count += 1print(count)
56

Проверка рассуждением: слева у всех 6 единиц, справа 3 фиксированные плюс s свободных. Нужно 3 + s < 6, то есть в десяти свободных битах не больше двух единиц: 1 + 10 + 45 = 56.

Наименьший и наибольший

Наименьший подходящий адрес — первый, который встретится при переборе по порядку: на нём цикл и останавливают. Наибольшее значение ищут перебором до конца, каждый раз запоминая лучшее. Найдём наименьший адрес компьютера нашей сети с 12 единицами:

from ipaddress import ip_network net = ip_network('172.20.76.0/22')for address in net.hosts():    if f'{address:b}'.count('1') == 12:        breakprint(address)
172.20.76.7

Наибольшая сумма октетов среди таких адресов ищется до конца сети ():

from ipaddress import ip_networknet = ip_network('172.20.77.140/22', strict=False)best = 0for address in net.hosts():    if f'{address:b}'.count('1') == 12:        octets = str(address).split('.')        best = max(best, sum(int(x) for x in octets))print(best)
492

Это 172.20.76.224, а не адрес из конца сети: у 79 в третьем октете уже 5 единиц, и на последний октет остаётся одна. Самый большой адрес и самая большая сумма октетов — разные вопросы.

Тонкости:размер перебора и неизвестная маска

Перебор сети /22 — 1024 адреса, /16 — 65 536, /12 — около миллиона: это ещё секунды. Сеть /8 — 16 миллионов адресов, её считают формулой (дополнительный урок).

Если маска не дана, сначала выбирают крайнюю допустимую маску (подтема 4). Наименьшее количество подходящих адресов — в самой маленькой сети (наибольшее p), наибольшее — в самой большой (наименьшее p): меньшая сеть целиком лежит внутри большей.

Итого

  • Фиксированныеединицы сетевой части — у всех адресов одни
  • Переборfor address in net, f'{address:b}'.count('1')
  • Компьютерыnet.hosts(); края проверить, а не вычесть два
  • Часть адресасрезы bits[:16], bits[16:24]
  • Крайний адреснаименьший — break, наибольший — max до конца

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
Сколько единиц в сетевой части каждого адреса сети 10.0.0.0/28?
ОтветСкрыть ответ
Ответ
2: в 10 = 00001010 две единицы, остальные сетевые биты — нули.
Вопрос 2
Какое наибольшее число единиц может быть в адресе компьютера сети 10.0.0.0/24?
ОтветСкрыть ответ
Ответ
9: сетевая часть даёт 2 единицы, свободных битов 8, но адрес из всех единиц — широковещательный: 2 + 8 − 1.
Вопрос 3
В сети 16 адресов. Сколько из них имеют чётное число единиц в двоичной записи?
ОтветСкрыть ответ
Ответ
8 — ровно половина: варианты свободных битов разбиваются на пары, отличающиеся последним битом.
Вопрос 4
Число 3 нечётное. А число единиц в его двоичной записи?
ОтветСкрыть ответ
Ответ
Чётное: 3 = 11₂, две единицы. Чётность числа и чётность числа единиц — разные свойства.
Вопрос 5
Какие символы строки bits из 32 битов адреса берёт срез bits[16:24]?
ОтветСкрыть ответ
Ответ
Третий октет: символы с индексами 16–23.

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Ровно восемь единиц в /29

В сети 192.168.1.0/29 сколько адресов содержат ровно восемь единиц в полной двоичной записи?

Введите число.

Три единицы в /28

Сколько адресов сети 10.0.0.0/28 содержат ровно три единицы в двоичной записи?

Введите число.

Наибольшее число единиц у компьютера

Какое наибольшее количество единиц может быть в двоичной записи адреса компьютера сети 192.168.0.0/24?

Введите число.

Чётное число единиц у компьютеров

В сети 192.168.1.0/29 сколько адресов, которые можно назначить компьютерам, содержат чётное число единиц в двоичной записи?

Введите число.

Количество единиц кратно 3

Сколько адресов сети 172.16.5.64/26 имеют количество единиц, кратное 3?

Введите число.

Число единиц не кратно 3

Сеть задана IP-адресом 201.33.148.0 и маской сети 255.255.255.240. Сколько в этой сети IP-адресов, для которых количество единиц в двоичной записи не кратно 3? В ответе укажи только число.

Введите число.

Третий байт: нулей столько же, сколько единиц

Сколько адресов сети 10.20.0.0/18 содержат в третьем байте одинаковое количество нулей и единиц?

Введите число.

Наименьший адрес с кратным 4 числом единиц

Сеть задана IP-адресом одного из входящих в неё узлов 180.45.101.7 и сетевой маской 255.255.224.0. Найди наименьший IP-адрес этой сети, который может быть назначен компьютеру и содержит в двоичной записи кратное 4 количество единиц. В ответе укажи адрес без разделителей.

Введите адрес без точек.

Наибольшая сумма октетов

Сеть задана IP-адресом 115.180.0.0 и сетевой маской 255.252.0.0. Определи наибольшую сумму октетов IP-адреса компьютера из этой сети, у которого количество единиц и количество нулей в двоичной записи одинаково.

Введите число.

Наименьшее количество адресов с 15 единицами

Узлы с IP-адресами 52.118.40.17 и 52.118.45.200 принадлежат одной сети. Какое наименьшее количество IP-адресов, в двоичной записи которых ровно 15 единиц, может содержаться в этой сети?

Введите число.