Подтема 4 из 6
Неизвестная маска
Как найти маску, если известны адрес узла и адрес сети, и когда два узла оказываются в одной сети.
Маска по адресу сети
Обратная задача: известны узел 172.20.77.140 и адрес его сети 172.20.76.0, а маска — нет. Какой она может быть?
Маску восстанавливают по битам: где единица адреса сохранилась, в маске 1, где пропала — 0, а совпавшие нули маску не определяют. Это то же равенство «адрес сети = адрес И маска», только неизвестна маска:
| Адрес | Сеть | Бит маски |
|---|---|---|
| 1 | 1 | только 1 — единицу надо сохранить |
| 1 | 0 | только 0 — единицу надо обнулить |
| 0 | 0 | 0 или 1 — «И» с нулём всегда 0 |
| 0 | 1 | невозможно — «И» не делает из нуля единицу |
Первые два октета совпадают, сравниваем третий: 77 = 01001101, 76 = 01001100. Шестой бит — единица в обоих: маска должна дойти хотя бы до него, это 16 + 6 = 22 единицы. Восьмой бит — 1 у адреса и 0 у сети: здесь в маске ноль. Седьмой бит — ноль в обоих, он может быть и сетевым, и узловым.
Все подходящие маски
Подходящие длины маски образуют отрезок L ≤ p ≤ C: L — позиция последней единицы адреса сети, C — сколько первых битов адреса и адреса сети совпадают. У нас L = 22, C = 23: маски /22 (третий байт 252) и /23 (254). Какую из них назвать, решает вопрос задачи. Выбери вопрос:
- наименьший третий байт
- 252самая короткая маска /22
- наибольший третий байт
- 254самая длинная маска /23
- больше всего единиц
- 23
- меньше всего нулей
- 9
- больше всего адресов
- 1024самая короткая маска оставляет больше свободных битов
- сколько масок
- 2
Найди первый октет, где адрес и сеть различаются, запиши оба октета битами. L — до последней единицы сети включительно, C — до первого различия. Совпадение целых октетов ещё не значит 255 в маске: 192 И 192 = 192 при октете маски 192.
Длин маски всего 33 — от 0 до 32, поэтому программа перебирает их все () и оставляет те, где адрес сети совпал с заданным (). Пройди по шагам длины от 21 до 24:
from ipaddress import ip_address, ip_network expected = ip_address('172.20.76.0')found = []for p in range(21, 25): net = ip_network(f'172.20.77.140/{p}', strict=False) if net.network_address == expected: found.append(p)print(found)from ipaddress import ip_address, ip_networkexpected = ip_address('172.20.76.0')found = []for p in range(33): net = ip_network(f'172.20.77.140/{p}', strict=False) if net.network_address == expected: found.append(p)print(found)print(ip_network(f'0.0.0.0/{min(found)}').netmask)Ответ берут из списка: — длины, 32 - p — нули, len — сколько масок. Октет маски — str(mask).split('.')[2] ( 2 — третья часть).
Два узла
Узлы 172.20.77.140 и 172.20.79.200 находятся в одной сети. Какая у неё самая длинная маска?
При общей маске два адреса в одной сети, пока граница маски не заходит дальше их совпадающих начальных битов. Третьи октеты: 77 = 01001101, 79 = 01001111 — совпадают первые шесть битов, всего C = 16 + 6 = 22. При p ≤ 22 сети одинаковы, при p ≥ 23 — разные.
Самая длинная общая маска — /22, это и есть маска задачи темы. Самая короткая маска, при которой узлы уже в разных сетях, — /23. Дальше первого различия сравнивать не нужно: сетевая часть уже разная.
Строим обе сети для каждой длины и сравниваем их:
from ipaddress import ip_networksame = []for p in range(33): a = ip_network(f'172.20.77.140/{p}', strict=False) b = ip_network(f'172.20.79.200/{p}', strict=False) if a == b: same.append(p)print(max(same))Для разных сетей ищут первую длину, где сети различаются, и останавливают цикл ():
from ipaddress import ip_network for p in range(20, 33): a = ip_network(f'172.20.77.140/{p}', strict=False) b = ip_network(f'172.20.79.200/{p}', strict=False) if a.network_address != b.network_address: breakprint(p)Тонкости:узел на краю сети
Узел не может совпадать с адресом сети или широковещательным адресом, поэтому самая длинная маска иногда на бит короче C. У узлов 172.20.72.0 и 172.20.79.200 совпадают 21 бит, но при /21 адрес 172.20.72.0 — сам адрес сети:
Поэтому программа проверяет и края сети ( ends, ):
from ipaddress import ip_address, ip_networka = ip_address('172.20.72.0')b = ip_address('172.20.79.200')best = 0for p in range(33): net = ip_network(f'{a}/{p}', strict=False) ends = (net.network_address, net.broadcast_address) if b in net and a not in ends and b not in ends: best = pprint(best)Итого
- По битам1 сохранилась — 1; пропала — 0; два нуля — любой
- L ≤ p ≤ Cот последней единицы сети до первого различия
- Перебор33 длины;
ip_network(f'{ip}/{p}', strict=False) - Два узлаодна сеть при p ≤ C, разные — при p > C
- Краяузел не может быть адресом сети или широковещательным
Проверьте себя
Ответь сначала сам, потом открой ответ.
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Третий байт маски
Для узла с IP-адресом 74.219.187.66 адрес сети равен 74.219.176.0. Чему равен третий слева байт маски? Ответ запиши в виде десятичного числа.
Введите число.
Подсказка
Где единица адреса сохранилась — в маске 1, где пропала — 0.
Решение
187 = 10111011, 176 = 10110000: четвёртый бит единица в обоих — маска до него единичная; пятый бит у узла 1, у сети 0 — в маске ноль. Маска одна, третий байт 11110000 = 240.
Решение программой
from ipaddress import ip_address, ip_network ps = [p for p in range(33) if ip_network(f'74.219.187.66/{p}', strict=False) .network_address == ip_address('74.219.176.0')]print(ip_network(f'0.0.0.0/{ps[0]}').netmask.packed[2])Ответ: 240
Наименьший последний байт маски
Для узла с IP-адресом 85.112.43.200 адрес сети равен 85.112.43.192. Чему равно наименьшее возможное значение последнего байта маски?
Введите число.
Подсказка
Наименьший октет маски — у самой короткой подходящей маски.
Решение
200 = 11001000, 192 = 11000000: последняя единица сети — на 26-й позиции (L = 26), первое различие — на 29-й (C = 28). Подходят маски /26, /27, /28, наименьший последний байт у /26 — 192.
Решение программой
from ipaddress import ip_address, ip_network expected = ip_address('85.112.43.192')ps = []for p in range(33): net = ip_network(f'85.112.43.200/{p}', strict=False) if net.network_address == expected: ps.append(p)mask = ip_network(f'0.0.0.0/{min(ps)}').netmaskprint(int(str(mask).split('.')[3]))Ответ: 192
Наибольшее число единиц маски
Для узла с IP-адресом 131.70.215.9 адрес сети равен 131.70.208.0. Каково наибольшее возможное количество единиц в маске?
Введите число.
Подсказка
Самая длинная маска доходит до первого различия адреса и сети.
Решение
215 = 11010111, 208 = 11010000: L = 20, первые 21 бит совпадают — C = 21. Наибольшее число единиц — 21.
Решение программой
from ipaddress import ip_address, ip_network ps = [p for p in range(33) if ip_network(f'131.70.215.9/{p}', strict=False) .network_address == ip_address('131.70.208.0')]print(max(ps))Ответ: 21
Наименьшее число нулей маски
Для того же узла 131.70.215.9 и сети 131.70.208.0 найди наименьшее возможное количество нулей в маске.
Введите число.
Подсказка
Меньше всего нулей — у самой длинной подходящей маски.
Решение
Подходят маски /20 и /21. Меньше всего нулей у самой длинной: 32 − 21 = 11.
Решение программой
from ipaddress import ip_address, ip_network ps = [p for p in range(33) if ip_network(f'131.70.215.9/{p}', strict=False) .network_address == ip_address('131.70.208.0')]print(32 - max(ps))Ответ: 11
Сколько масок возможно
Для узла с IP-адресом 200.15.77.130 адрес сети равен 200.15.77.128. Для скольких различных значений маски это возможно?
Введите число.
Подсказка
Подходят все длины от L до C.
Решение
130 = 10000010, 128 = 10000000: L = 25, первое различие на 31-й позиции — C = 30. Подходят длины от 25 до 30, это 6 масок.
Решение программой
from ipaddress import ip_address, ip_network ps = [p for p in range(33) if ip_network(f'200.15.77.130/{p}', strict=False) .network_address == ip_address('200.15.77.128')]print(len(ps))Ответ: 6
Наибольшее число единиц
Для узла с IP-адресом 141.97.58.197 адрес сети равен 141.97.58.192. Каково наибольшее возможное количество единиц в разрядах маски?
Введите число.
Подсказка
C — до первой единицы узла, которая в адресе сети стала нулём.
Решение
197 = 11000101, 192 = 11000000: L = 26, первая единица узла, обнулённая в сети, — на 30-й позиции, C = 29. Наибольшее число единиц — 29.
Решение программой
from ipaddress import ip_address, ip_network ps = [p for p in range(33) if ip_network(f'141.97.58.197/{p}', strict=False) .network_address == ip_address('141.97.58.192')]print(max(ps))Ответ: 29
Наибольшее количество адресов
Для того же узла 141.97.58.197 и сети 141.97.58.192 найди наибольшее возможное количество адресов в этой сети.
Введите число.
Подсказка
Больше всего адресов — у самой короткой маски.
Решение
Подходят маски от /26 до /29. Больше всего адресов в сети с самой короткой маской /26: 2⁶ = 64.
Решение программой
from ipaddress import ip_address, ip_network ps = [p for p in range(33) if ip_network(f'141.97.58.197/{p}', strict=False) .network_address == ip_address('141.97.58.192')]print(2 ** (32 - min(ps)))Ответ: 64
Самая длинная общая маска
Даны узлы 10.30.52.1 и 10.30.55.250. Сколько единиц в самой длинной общей маске, при которой они ещё находятся в одной сети?
Введите число.
Подсказка
Граница общей маски не может заходить дальше совпадающих начальных битов.
Решение
52 = 00110100, 55 = 00110111: первые шесть битов третьего октета совпадают, C = 16 + 6 = 22. При маске /22 узлы в одной сети, при /23 — уже в разных.
Решение программой
from ipaddress import ip_address, ip_network same = []for p in range(33): a = ip_network(f'10.30.52.1/{p}', strict=False) b = ip_network(f'10.30.55.250/{p}', strict=False) if a == b: same.append(p)print(max(same))Ответ: 22
Наибольшее число единиц маски для двух узлов
Узлы с IP-адресами 90.14.200.33 и 90.14.203.140 находятся в одной сети. Чему равно наибольшее возможное количество единиц в маске этой сети?
Введите число.
Подсказка
Проверь, что при самой длинной маске узлы не совпадают с краями сети.
Решение
200 = 11001000, 203 = 11001011: C = 16 + 6 = 22. При /22 сеть 90.14.200.0 — 90.14.203.255, и оба узла в ней обычные адреса, поэтому ответ 22.
Решение программой
from ipaddress import ip_address, ip_network def net(node, p): return ip_network(f'{node}/{p}', strict=False) def ordinary(node, p): n = net(node, p) address = ip_address(node) return address not in (n.network_address, n.broadcast_address) a, b = '90.14.200.33', '90.14.203.140'same = [p for p in range(33) if net(a, p) == net(b, p)]print(max(p for p in same if ordinary(a, p) and ordinary(b, p)))Ответ: 22
Наименьшее количество адресов общей сети
Для тех же узлов 90.14.200.33 и 90.14.203.140 найди наименьшее возможное количество адресов в сети, которой они оба принадлежат.
Введите число.
Подсказка
Найди самую длинную общую маску.
Решение
Меньше всего адресов — в сети с самой длинной общей маской /22: 2¹⁰ = 1024.
Решение программой
from ipaddress import ip_address, ip_network def net(node, p): return ip_network(f'{node}/{p}', strict=False) def ordinary(node, p): n = net(node, p) address = ip_address(node) return address not in (n.network_address, n.broadcast_address) a, b = '90.14.200.33', '90.14.203.140'same = [p for p in range(33) if net(a, p) == net(b, p)]p = max(p for p in same if ordinary(a, p) and ordinary(b, p))print(2 ** (32 - p))Ответ: 1024
Разные сети: наименьшее число единиц
Узлы с IP-адресами 156.71.33.90 и 156.71.33.120 находятся в разных сетях с одинаковой маской. Чему равно наименьшее возможное количество единиц в маске?
Введите число.
Подсказка
Разные сети — граница маски дальше первого различия.
Решение
90 = 01011010, 120 = 01111000: совпадают первые два бита последнего октета, C = 24 + 2 = 26. Сети разные, когда граница заходит за первое различие: p ≥ 27.
Решение программой
from ipaddress import ip_address, ip_network def net(node, p): return ip_network(f'{node}/{p}', strict=False) def ordinary(node, p): n = net(node, p) address = ip_address(node) return address not in (n.network_address, n.broadcast_address) a, b = '156.71.33.90', '156.71.33.120'same = [p for p in range(33) if net(a, p) == net(b, p)]print(max(same) + 1)Ответ: 27
Узел на краю сети
Узлы с IP-адресами 61.5.96.0 и 61.5.111.7 находятся в одной сети. Чему равно наибольшее возможное количество единиц в маске? Будь внимателен к первому адресу.
Введите число.
Подсказка
При длинной маске адрес 61.5.96.0 становится адресом сети — такой маски быть не может.
Решение
96 = 01100000, 111 = 01101111: C = 16 + 4 = 20. Но при /20 и /19 узел 61.5.96.0 — сам адрес сети. При /18 сеть 61.5.64.0 — 61.5.127.255, оба узла обычные: ответ 18.
Решение программой
from ipaddress import ip_address, ip_network def net(node, p): return ip_network(f'{node}/{p}', strict=False) def ordinary(node, p): n = net(node, p) address = ip_address(node) return address not in (n.network_address, n.broadcast_address) a, b = '61.5.96.0', '61.5.111.7'same = [p for p in range(33) if net(a, p) == net(b, p)]print(max(p for p in same if ordinary(a, p) and ordinary(b, p)))Ответ: 18
Третий байт маски общей сети
Узлы с IP-адресами 18.240.130.5 и 18.240.141.77 находятся в одной сети. Укажи наибольшее возможное значение третьего слева байта маски этой сети.
Введите число.
Подсказка
Найди самую длинную общую маску и её третий байт.
Решение
130 = 10000010, 141 = 10001101: C = 16 + 4 = 20, оба узла при /20 обычные. Третий байт маски /20 — 11110000 = 240.
Решение программой
from ipaddress import ip_address, ip_network def net(node, p): return ip_network(f'{node}/{p}', strict=False) def ordinary(node, p): n = net(node, p) address = ip_address(node) return address not in (n.network_address, n.broadcast_address) a, b = '18.240.130.5', '18.240.141.77'same = [p for p in range(33) if net(a, p) == net(b, p)]p = max(p for p in same if ordinary(a, p) and ordinary(b, p))print(ip_network(f'0.0.0.0/{p}').netmask.packed[2])Ответ: 240
Третий байт маски разных сетей
Узлы с IP-адресами 205.66.157.48 и 205.66.149.230 находятся в разных сетях, маски которых одинаковы. Укажи наименьшее возможное значение третьего слева байта этой маски. Ответ запиши в виде десятичного числа.
Введите число.
Подсказка
Самая короткая маска разных сетей на бит длиннее совпадения.
Решение
157 = 10011101, 149 = 10010101: C = 16 + 4 = 20, разные сети начинаются с /21. Третий байт маски /21 — 11111000 = 248.
Решение программой
from ipaddress import ip_address, ip_network def net(node, p): return ip_network(f'{node}/{p}', strict=False) def ordinary(node, p): n = net(node, p) address = ip_address(node) return address not in (n.network_address, n.broadcast_address) a, b = '205.66.157.48', '205.66.149.230'same = [p for p in range(33) if net(a, p) == net(b, p)]p = max(same) + 1print(ip_network(f'0.0.0.0/{p}').netmask.packed[2])Ответ: 248
Второй байт маски
Два узла, находящиеся в одной сети, имеют IP-адреса 77.180.12.9 и 77.184.250.4. Укажи наибольшее возможное значение второго слева байта маски сети. Ответ запиши в виде десятичного числа.
Введите число.
Подсказка
Узлы различаются уже во втором байте — сравни его биты.
Решение
Первое различие — во втором байте: 180 = 10110100, 184 = 10111000, совпадают четыре бита, C = 8 + 4 = 12. Второй байт маски /12 — 11110000 = 240.
Решение программой
from ipaddress import ip_address, ip_network def net(node, p): return ip_network(f'{node}/{p}', strict=False) def ordinary(node, p): n = net(node, p) address = ip_address(node) return address not in (n.network_address, n.broadcast_address) a, b = '77.180.12.9', '77.184.250.4'same = [p for p in range(33) if net(a, p) == net(b, p)]p = max(p for p in same if ordinary(a, p) and ordinary(b, p))print(ip_network(f'0.0.0.0/{p}').netmask.packed[1])Ответ: 240