В терминологии сетей TCP/IP маской сети называется двоичное число, определяющее, какая часть IP-адреса узла сети относится к адресу сети, а какая — к адресу самого узла в этой сети. При этом в маске сначала (в старших разрядах) стоят единицы, а затем с некоторого места — нули.
Адрес сети получается в результате применения поразрядной конъюнкции к заданному IP-адресу узла и маске.
Например, если IP-адрес узла равен 231.32.255.131, а маска равна 255.255.240.0, то адрес сети равен 231.32.240.0.
Узлы с IP-адресами 157.220.185.237 и 157.220.184.230 принадлежат одной сети. Какое наименьшее количество IP-адресов, в двоичной записи которых ровно 15 единиц, может содержаться в этой сети?
Приведём решение на языке Python.
from ipaddress import *
ip1 = ip_address('157.220.185.237')
ip2 = ip_address('157.220.184.230')
otv = []
for mask in range(15,33):
net = ip_network(f'157.220.185.237/{mask}', 0)
if (ip1 in net) and (ip2 in net):
count = 0
for ip in net:
if f'{ip:b}'.count('1') == 15:
count += 1
otv.append(count)
print(min(otv))
Ответ: 9.
Приведём решение Данила Шарлова на языке Python.
from ipaddress import ip_network, ip_address
ip_b = ip_address('157.220.184.230')
for mask in range(32, -1, -1):
net = ip_network(f'157.220.185.237/{mask}',0)
if ip_b in net:
print(sum(bin(int(ip)).count('1')==15 for ip in net))
break
Приведём аналитическое решение Юрия Красильникова.
Ip-адреса из условия выглядят так:
10011101110111001011100111101101
10011101110111001011100011100110
11111111111111111111111000000000
Под адресами - маска с максимально возможной длиной адреса сети (до первого различающегося бита). Длина номера узла (количество нулей) в этой маске равно 9.
Число единиц в поле адреса сети - 14. Следовательно, поле номера узла должно содержать одну единицу. Число способов поставить единицу на одно из 9 мест - 9.
Приведём решение Юрия Красильникова на языке Python.
import ipaddress,math
s1 = bin(int(ipaddress.ip_address('157.220.185.237')))[2:].zfill(32) # Двоичное представление адреса сети 1
s2 = bin(int(ipaddress.ip_address('157.220.184.230')))[2:].zfill(32) # Двоичное представление адреса сети 2
for l in range(32):
if s1[l] != s2[l]: break # l - максимальная длина адреса сети
num = 32-l # длина номера узла
k = 15-s1[:l].count('1') # количество единиц в номере узла
print(math.comb(num,k)) # число сочетаний

