Задание №13 — Маски подсети
В терминологии сетей TCP/IP маской сети называют двоичное число, которое показывает, какая часть IP-адреса узла сети относится к адресу сети, а какая – к адресу узла в этой сети. Адрес сети получается в результате применения поразрядной конъюнкции к заданному адресу узла и маске сети. Сеть задана IP-адресом 113.216.0.0 и маской сети 255.255.224.0.
Сколько в этой сети IP-адресов, для которых сумма единиц в двоичной записи IP-адреса чётна?
В ответе укажите только число.
Правильный ответ
4096
Пояснение
Решение:
Маска 255.255.224.0 в двоичном виде — 11111111.11111111.11100000.00000000, в ней 19 единиц. Значит, старшие 19 битов — это адрес сети, они одинаковы у всех её узлов, а младшие битов узловые: сеть содержит адреса. Адрес сети равен исходному: 0 & 224 = 0, то есть 113.216.0.0.
Ключевая идея: сумма единиц всего адреса — это сумма единиц фиксированной части плюс сумма единиц узловой части, поэтому чётность суммы зависит только от чётности числа единиц в 13 свободных битах (если фиксированная часть даёт чётный вклад). Фиксированные биты — 01110001.11011000.000: в 113 четыре единицы, в 216 тоже четыре, в трёх старших нулях — ни одной, всего 8 — число чётное.
Остаётся посчитать, у скольких 13-битных наборов число единиц чётно. Их ровно половина: смена последнего бита на противоположный превращает каждый «чётный» набор в «нечётный» и обратно, то есть задаёт взаимно однозначное соответствие между этими двумя группами. Поэтому подходящих адресов .
Проверка программой:
from itertools import product
def to_bits(s):
return ''.join(format(int(x), '08b') for x in s.split('.'))
ip = to_bits('113.216.0.0')
mask = to_bits('255.255.224.0')
k = mask.count('1')
head = ip[:k]
addrs = [head + ''.join(t) for t in product('01', repeat=32 - k)]
print(sum(1 for a in addrs if a.count('1') % 2 == 0))
Ответ: 4096