К содержанию

Задание 10

Маска подсети

Как по IP-адресу и маске найти адрес сети, её края и число адресов — и как найти маску, если её не дали.

6 подтем · 54 задачи + 7 дополнительных · базовый · ≈ 3 мин

Подтема 1 из 6

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

Что такое IP-адрес и маска, как записать их битами и какие маски вообще бывают.

Как устроена тема

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

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

Адрес и маску записывают битами: маска делит адрес на часть сети и часть узла, и дальше всё видно по битам. Вручную обычно хватает одного октета, а программа делает то же модулем ipaddress. Сначала разберём, что сказано в условии:

В условииЧто это значит
узел 172.20.77.140адрес одного компьютера сети — четыре числа по 8 битов
маска 255.255.252.0граница: слева от неё биты сети, справа — номер компьютера
наибольший адрес, который может быть назначен компьютерупоследний адрес сети не годится — нужен предыдущий
сумма значений октетовсложить четыре числа адреса

Тема состоит из шести подтем — у каждой своя страница. Идём по ним по порядку:

  1. IP-адрес и маска — ты сейчас здесь.
  2. Адрес сети и границы сети — края сети и ответ задачи темы: 525.
  3. Количество адресов и номер узла — сколько адресов в сети и какой номер у компьютера.
  4. Неизвестная маска — как найти маску, если её не дали.
  5. Адреса с условием на двоичную запись — сколько адресов с нужным числом единиц.
  6. Маска по условию и сочетания — дополнительный урок для редких задач.

Почти везде задачу можно решить и вручную, и программой — выбирай вкладку «Вручную» или «Python». На экзамене подойдёт любой способ, а второй пригодится для проверки.

32 бита

Что на самом деле записано в 172.20.77.140?

IP-адрес — 32 бита: четыре октета по восемь битов, каждый октет записан десятичным числом от 0 до 255. Бит — одна двоичная цифра, 0 или 1; октет (байт) — восемь битов. Точки только разделяют октеты.

Позиции октета справа налево стоят 1, 2, 4, 8, 16, 32, 64, 128. Единица в позиции добавляет её значение к числу:

Позиция1286432168421
Бит10001100

10001100₂ = 128 + 8 + 4 = 140. Октет всегда записывают ровно восемью битами: 20 = 10100₂, но внутри адреса это 00010100 — нули слева сохраняют позиции.

Вручную

Значения позиций проверяют от большего к меньшему: в 140 помещается 128 — пишем 1, остаётся 12; 64, 32 и 16 не помещаются — три нуля; 8 помещается — 1, остаётся 4; 4 помещается — 1, остаётся 0; дальше нули. Получаем 10001100.

ОктетБиты
17210101100
2000010100
7701001101
14010001100
Python

Тот же перебор позиций делают : частное — очередной бит, остаток — что осталось. Пройди по шагам:

n = 140bits = ''for w in [128, 64, 32, 16, 8, 4, 2, 1]:    bits += str(n // w)    n = n % wprint(bits)
10001100

Весь адрес сразу даёт стандартный модуль : ip_address превращает строку в адрес, запись f'{address:b}' () — в 32 бита с нулями слева, а int(address) — в одно целое число:

from ipaddress import ip_addressaddress = ip_address('172.20.77.140')print(f'{address:b}')print(int(address))
10101100000101000100110110001100 2887011724
Тонкости:255 и 256, bin

Наибольший октет — 11111111₂ = 255, а значений у октета 256: от 0 до 255, 2⁸ вариантов. Не путай наибольшее значение с количеством.

Функция возвращает '0b10100' — с приставкой и без нулей слева. Считать по ней нули адреса нельзя: их часть потеряна.

Маска

Маска — тоже 32 бита: сначала единицы, потом нули. Единицы отмечают часть сети, нули — часть узла. Часть сети одинакова у всех адресов сети, часть узла различает компьютеры внутри неё.

В маске 255.255.252.0 два октета 255 — 16 единиц, 252 = 11111100 — ещё 6 единиц и 2 нуля, в последнем октете 8 нулей. Всего 22 единицы: первые 22 бита адреса — сеть, последние 10 — узел. Граница проходит внутри третьего октета, а не по точке:

Адрес 172.20.77.140 и маска /22 по битам: граница проходит после шестого бита третьего октета. Часть узла — два последних бита третьего октета и весь четвёртый, 10 бит.

Маску коротко записывают числом единиц: 255.255.252.0 — это /22. Обозначим p — длину префикса (число единиц маски), h — число битов части узла: p + h = 32, у /22 h = 10.

Единица маски не требует единицы в адресе: она говорит только, что этот бит — сетевой и одинаков у всех адресов сети. Сам бит может быть и нулём, и единицей — у 77 сетевые биты третьего октета 010011.

Допустимые маски

У маски единицы идут подряд слева, поэтому октет маски бывает только девяти видов, и смешанный октет в маске один. Перед ним — октеты 255, после него — октеты 0.

ЕдиницБитыОктет
0000000000
110000000128
211000000192
311100000224
411110000240
511111000248
611111100252
711111110254
811111111255

Таблицу легко восстановить: 128, 128 + 64 = 192, 192 + 32 = 224 и так далее. Число 250 = 11111010 в маске невозможно — после нуля снова единица. Маска 255.0.255.0 тоже невозможна.

Вручную

Маску /20 строят слева: 16 единиц — два октета 255, оставшиеся 4 единицы — 11110000 = 240, последний октет 0. Получаем 255.255.240.0. Обратно: 255.255.252.0 — 8 + 8 + 6 = 22 единицы.

Python

ip_network строит сеть по записи «адрес/маска», свойство netmask — её маска четырьмя октетами. Адрес 0.0.0.0 здесь только заготовка:

from ipaddress import ip_networkfor p in [20, 22, 24, 26]:    print(p, ip_network(f'0.0.0.0/{p}').netmask)
20 255.255.240.0 22 255.255.252.0 24 255.255.255.0 26 255.255.255.192

Допустимость маски проверяют по 32 битам: «после нуля снова единица» — это :

from ipaddress import ip_addressfor mask in ['255.255.252.0', '255.255.250.0']:    bits = f'{ip_address(mask):b}'    print(mask, '01' not in bits)
255.255.252.0 True 255.255.250.0 False

Итого

  • IP-адрес32 бита, четыре октета от 0 до 255
  • Октетровно 8 битов, нули слева сохраняют позиции
  • Маскаединицы — сеть, нули — узел; сначала единицы
  • /pp единиц маски, h = 32 − p битов узла
  • Pythonf'{address:b}', ip_network(…).netmask

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

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

Вопрос 1
Запиши октет 20 восемью битами.
ОтветСкрыть ответ
Ответ
00010100: 20 = 16 + 4, нули слева сохраняют позиции.
Вопрос 2
Переведи октет 11001000 в число.
ОтветСкрыть ответ
Ответ
200 = 128 + 64 + 8.
Вопрос 3
Запиши маску /20 четырьмя октетами.
ОтветСкрыть ответ
Ответ
255.255.240.0: 16 единиц — два октета 255, ещё 4 единицы — 11110000 = 240.
Вопрос 4
Может ли октет маски быть равен 250?
ОтветСкрыть ответ
Ответ
Нет: 250 = 11111010, после нуля снова единица.
Вопрос 5
Сколько битов части узла у маски 255.255.255.224?
ОтветСкрыть ответ
Ответ
5: 224 = 11100000, единиц 8 + 8 + 8 + 3 = 27, нулей 32 − 27.

Практика

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

Октет в двоичной записи

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

Введите восемь битов.

Единицы октета 37

Сколько единиц в двоичной записи октета 37?

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

Единицы адреса 192.168.10.173

Сколько единиц в полной двоичной записи адреса 192.168.10.173?

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

Биты части узла

Маска равна 255.255.254.0. Сколько битов в части узла?

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

Запиши маску /27 в виде четырёх десятичных чисел.

Введите маску: четыре числа через точку.

Маска с 29 единицами

Маска имеет вид 255.255.255.X и содержит 29 единиц. Найди X.

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

Маски вида 255.255.X.0

Сколько существует допустимых масок вида 255.255.X.0?

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