№13 IP адресация

Задание 13: IP-адресация и маска подсети

  • Тема: работа с IP-адресами, масками подсети, адресами сети и широковещательными адресами.
  • Ответ: целое число или слово.
  • Балл: 1. Время: 3-4 мин. Сложность: повышенная (средний процент выполнения: 44%).

Задания: N13.IP-адресация и маска подсети


Основные понятия

IP-адрес

32-битное число (IPv4), записывается четырьмя ,байтами(октетами) от 0 до 255, разделёнными точками. Пример: 192.168.1.3 11000000.10101000.00000001.00000011

IP-адрес состоит из двух частей:

  • Адрес сети - общая часть для всех устройств в сети (биты, где в маске стоят 1).
  • Адрес узла (хоста) - часть, идентифицирующая конкретное устройство (биты, где в маске стоят 0).

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

32-битное число, определяющее, какая часть IP-адреса - адрес сети, а какая - адрес узла.

Правило: в маске сначала идут единицы (сетевая часть), затем нули (хостовая часть). Нули и единицы не перемежаются.

Допустимые значения каждого октета маски: 0, 128, 192, 224, 240, 248, 252, 254, 255

Примеры допустимых масок:

Маска Двоичная запись Префикс
255.0.0.0 11111111.00000000.00000000.00000000 /8
255.255.0.0 11111111.11111111.00000000.00000000 /16
255.255.255.0 11111111.11111111.11111111.00000000 /24
255.255.248.0 11111111.11111111.11111000.00000000 /21
255.255.255.128 11111111.11111111.11111111.10000000 /25

CIDR-нотация: 192.168.0.0/24 - запись, где /24 означает количество единиц в маске (префикс).


Адрес сети

Получается побитовой операцией AND (конъюнкция) между IP-адресом и маской. В адресе сети все биты хостовой части равны 0.

Пример:

IP-адрес:  135.213.234.10  →  10000111.11010101.11101010.00001010
Маска:     255.255.248.0   →  11111111.11111111.11111000.00000000
                                                          AND
Адрес сети: 135.213.232.0  →  10000111.11010101.11101000.00000000

Широковещательный адрес

Адрес, где все биты хостовой части равны 1. Используется для отправки данных всем устройствам сети. Не назначается конкретным устройствам.

Получается операцией OR между адресом сети и инвертированной маской.

Пример (продолжение):

Адрес сети:          135.213.232.0  →  10000111.11010101.11101000.00000000
Инверсия маски:      0.0.7.255      →  00000000.00000000.00000111.11111111
                                                                       OR
Широковещательный:   135.213.239.255 → 10000111.11010101.11101111.11111111

Пример. Зачем нужна маска?

image

Пусть есть некий район Эчпочмаковский с номером 192, в этом районе есть улица Казанская с номером 168 на которой стоят 3 дома и в каждой по 3 квартиры.

У нас есть IP-адрес 192(район).168(улица).1(дом).5(квартира) из 5 кв 1 дома, и чтобы узнать адрес сети всей улицы, нужно сделать побитовую коньюкцию с маской подсети, где на месте номера района и номера улицы будут 1, а на месте где дом и квартира 0

Получается IP-адрес: 192.168.1.5 или 11000000.10101000.00000001.00000101

Маска подсети: 111111111.11111111.00000000.00000000 или 255.255.0.0

Тогда адрес сети улицы будет: 11000000.10101000.00000000.00000000 или 192.168.0.0


Диапазон адресов хостов

Все адреса между адресом сети и широковещательным (не включая их).

Правило: в любой сети всегда зарезервированы 2 адреса, которые нельзя назначить устройствам:

  • первый адрес диапазона - адрес сети (все биты хостовой части = 0);
  • последний адрес диапазона - широковещательный адрес (все биты хостовой части = 1).

Количество адресов в сети: 2^(32 - префикс) Количество хостов: 2^(32 - префикс) - 2 (вычитаем эти 2 зарезервированных адреса)

Пример: маска /21 (255.255.248.0):

  • Количество адресов: 2^(32-21) = 2^11 = 2048
  • Количество хостов: 2048 - 2 = 2046

Алгоритм решения

  1. Перевести IP-адрес и маску в двоичный вид (по октетам).
  2. Найти адрес сети: IP AND маска.
  3. Найти широковещательный адрес: адрес_сети OR (инверсия маски).
  4. Определить диапазон адресов хостов.
  5. Ответить на конкретный вопрос задачи.
  6. Перевести результат обратно в десятичный вид.

Типы заданий

Тип Что дано Что найти
1 IP + маска адрес сети
2 IP + адрес сети наименьший возможный байт маски
3 маска количество возможных адресов хостов
4 IP + маска количество адресов по условию в диапазоне
5 IP + маска принадлежит ли адрес данной сети
6 IP + маска широковещательный адрес
7 несколько IP + маска сколько устройств в одной подсети

Полезные команды Python

Перевод систем счисления

# Десятичное - двоичное (строка без '0b')
bin(83)          # '0b1010011'
f"{83:08b}"      # '01010011'  <- удобнее, с ведущими нулями

# Двоичное - десятичное
int("01010011", 2)   # 83

Побитовые операции

A B A AND B A OR B
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1

AND даёт 1 только если оба бита = 1 (используется для нахождения адреса сети). OR даёт 1 если хотя бы один бит = 1 (используется для нахождения широковещательного адреса).

a = 0b10111001   # 185
b = 0b11111000   # 248

a & b    # AND (конъюнкция)  - нахождение адреса сети
a | b    # OR  (дизъюнкция) - нахождение широковещательного адреса
~a       # NOT (инверсия)   - инверсия маски (осторожно: даёт отрицательное число!)
a ^ b    # XOR

# Инверсия маски безопасно (для 8-битного октета):
~b & 0xFF        # 0b00000111 = 7

# Сдвиги
a >> 1   # сдвиг вправо (деление на 2)
a << 1   # сдвиг влево  (умножение на 2)

Работа с октетами IP-адреса

ip_str = "185.49.83.72"
octets = list(map(int, ip_str.split(".")))  # [185, 49, 83, 72]

# AND двух адресов октет за октетом
mask = [255, 255, 248, 0]
net = [a & b for a, b in zip(octets, mask)]  # [185, 49, 80, 0]
print(".".join(map(str, net)))               # '185.49.80.0'

# Двоичное представление каждого октета
for o in octets:
    print(f"{o:08b}")

Модуль ipaddress

import ipaddress

net = ipaddress.ip_network("135.213.232.0/21", strict=False)

net.network_address    # IPv4Address('135.213.232.0')
net.broadcast_address  # IPv4Address('135.213.239.255')
net.netmask            # IPv4Address('255.255.248.0')
net.prefixlen          # 21
net.num_addresses      # 2048

# Кол-во хостов (без адреса сети и широковещательного)
len(list(net.hosts()))  # 2046

# Принадлежит ли IP сети
ip = ipaddress.ip_address("135.213.234.10")
ip in net              # True

# Создать сеть из IP + маска
net2 = ipaddress.ip_network(f"185.49.83.72/255.255.248.0", strict=False)

# Перебор адресов в диапазоне (для типа 4)
for host in net.hosts():
    last = int(host) & 0xFF   # правый байт
    binary = f"{last:08b}"
    if "000" not in binary:
        print(host)

Разбор примера: нахождение минимального байта маски

Задача: для узла с IP-адресом 185.49.83.72 адрес сети равен 185.49.80.0. Чему равен наименьший возможный третий байт маски?

Решение:

Переводим третьи байты в двоичный вид:

IP-адрес (3-й байт):   83 → 01010011
Адрес сети (3-й байт): 80 → 01010000

Биты совпадают в позициях 1-6 (слева), различаются в 7-8 позициях. Но там где 00, мы можем поставить 0 или 1, так как минимально езначение то ставим 0.

Маска должна иметь единицы там, где биты совпадают, и нули там, где различаются.

Минимальная маска - та, где как можно больше нулей. Первые 4 бит совпадают, значит маска минимум 11110000 = 240.

Ответ: 240


Разбор примера: нахождение максимального байта маски по числу хостов

Задача: IP-адрес сети 176.112.100.128, в ней может быть 14 компьютеров. Чему равен максимально возможный крайний правый байт маски сети?

Шаг 1. Определяем нужное количество адресов

14 компьютеров + 2 зарезервированных = 16 адресов.

Шаг 2. Определяем количество бит под хостовую часть

Нужно 2^n >= 162^4 = 16n = 4 бита под хосты.

Шаг 3. Составляем последний байт маски

В байте 8 бит. 4 бита - под хосты (нули в маске), оставшиеся 4 - под сеть (единицы):

11110000

Шаг 4. Переводим в десятичное

print(int("11110000",2))

Максимальный байт маски - это когда единиц как можно больше (нулей как можно меньше), то есть под хосты отведено ровно столько бит, сколько необходимо. Меньше нулей = больше значение байта маски.

Ответ: 240


Разбор примера: подсчёт адресов по условию на количество единиц

Задача: сеть задана IP-адресом 122.159.136.144 и маской 255.255.255.248. Сколько в этой сети IP-адресов, для которых количество единиц в двоичной записи не кратно 4?

Шаг 1. Определяем диапазон адресов сети

Последний байт маски 248 = 11111000 - три нуля, значит 2^3 = 8 адресов в сети.

Правило: шаг сети = 256 - последний байт маски = 256 - 248 = 8 Сети начинаются с кратных 8 чисел: ...136, 144, 152... Диапазон: 144 - 151 (144 + 8 - 1 = 151)

Все IP-адреса сети:

IP-адрес Последний байт
122.159.136.144 144
122.159.136.145 145
... ...
122.159.136.151 151

Шаг 2. Считаем единицы в первых трёх байтах (они одинаковы для всех адресов)

122 → 01111010 → 5 единиц
159 → 10011111 → 6 единиц
136 → 10001000 → 2 единицы
         Итого: 13

Шаг 3. Таблица: единицы в последнем байте + итог по всему адресу

Последний байт Двоично Единиц Итого (13 + N) Кратно 4?
144 10010000 2 15 нет
145 10010001 3 16 да
146 10010010 3 16 да
147 10010011 4 17 нет
148 10010100 3 16 да
149 10010101 4 17 нет
150 10010110 4 17 нет
151 10010111 5 18 нет

Шаг 4. Считаем подходящие адреса

Не кратно 4: 144, 147, 149, 150, 151 - итого 5.

Решение на Python:

bits = bin(122).count("1") + bin(159).count("1") + bin(136).count("1")  # = 13

otv = 0
for x in range(144, 152):  # 8 адресов: 144..151
    a = bits + bin(x).count("1")
    if a % 4 != 0:
        otv += 1
print(otv)  # 5

Ответ: 5


Полезные формулы

Что найти Формула
Адрес сети IP AND маска
Широковещательный адрес адрес_сети OR (NOT маска)
Количество адресов в сети 2^(32 - префикс)
Количество хостов 2^(32 - префикс) - 2
Префикс из маски посчитать единицы в двоичной записи маски

Разбор примера: нахождение максимального адреса компьютера в сети

Задача: сеть задана IP-адресом узла 98.81.154.195 и маской 255.252.0.0. Найдите наибольший IP-адрес, который может быть назначен компьютеру. Ответ запишите без разделителей.

Шаг 1. Переводим маску в двоичный вид

255 → 11111111
252 → 11111100
  0 → 00000000
  0 → 00000000

Маска: 11111111.11111100.00000000.00000000
       |-- 14 бит сети --|---- 18 бит хостов ----|

Шаг 2. Находим адрес сети (IP AND маска)

Первый, третий и четвёртый байты маски очевидны (255 и 0). Считаем только второй:

IP:   81 → 01010001
Маска 252 → 11111100
               AND
           01010000 = 80

Адрес сети: 98.80.0.0

Шаг 3. Находим широковещательный адрес

Широковещательный адрес - все биты хостовой части заменяем на 1.

Во втором байте последние 2 бита - хостовые:

Сетевая часть байта: 010100 → ставим хостовые биты в 1
010100|11 = 01010011 = 83

Третий и четвёртый байты полностью хостовые - заменяем на 255:

Широковещательный адрес: 98.83.255.255

Шаг 4. Максимальный адрес компьютера

Максимальный адрес хоста = широковещательный адрес - 1

98.83.255.255 - 1 = 98.83.255.254

Решение на Python:

import ipaddress

net = ipaddress.ip_network("98.81.154.195/255.252.0.0", strict=False)
max_host = net.broadcast_address - 1

# Ответ без разделителей
print("".join(str(max_host).split(".")))  # 9883255254

Ответ: 9883255254


Разбор примера: нахождение максимального адреса компьютера (2)

Задача: сеть задана IP-адресом узла 205.99.68.249 и маской 255.255.248.0. Найдите наибольший IP-адрес, который может быть назначен компьютеру. Ответ запишите без разделителей.

Шаг 1. Определяем шаг подсети

Третий байт маски 248 = 11111000 - три нуля, четвёртый байт маски 0 = 00000000 - восемь нулей.

шаг по третьему байту = 256 - 248 = 8

Сети начинаются: ...56, 64, 72... - берём ближайшее кратное 8, не превышающее 68.

Шаг 2. Находим адрес сети

Первый, второй, четвёртый байты очевидны (255, 255 и 0). Считаем только третий:

IP:    68 → 01000100
Маска 248 → 11111000
               AND
           01000000 = 64

Адрес сети: 205.99.64.0

Шаг 3. Находим широковещательный адрес

Хостовые части - последние 3 бита третьего байта и весь четвёртый байт - заменяем на 1:

Третий байт:  64 + 7 = 71  (01000000 | 00000111 = 01000111)
Четвёртый байт: 255

Широковещательный адрес: 205.99.71.255

Шаг 4. Максимальный адрес компьютера

205.99.71.255 - 1 = 205.99.71.254

Решение на Python:

ip = [205, 99, 68, 249]
mask = [255, 255, 248, 0]

net = [a & b for a, b in zip(ip, mask)]
broadcast = [n | (255 - m) for n, m in zip(net, mask)]
max_host = broadcast[:]
max_host[3] -= 1

print("".join(str(x) for x in max_host))  # 2059971254

Ответ: 2059971254


Материалы будут дополняться.