Сетевое программирование звучит сложно? Библиотека ipaddress в Python превращает рутину в удовольствие. Показываю на примерах, которые поймет даже девятиклассник.
Привет! Готовишься к ЕГЭ по информатике или просто увлекаешься программированием? Одна из самых скучных и запутанных тем — это сети и IP-адреса. Рисовать таблицы, вычислять маски вручную... Скукотища!
А что, если я скажу, что всю эту рутину можно доверить Python? Сегодня разберем библиотеку ipaddress, которая встроена в язык и делает из тебя сетевого гуру буквально за 5 минут.
Установка? Не нужно!
Первое преимущество — библиотека ipaddress является частью стандартной библиотеки Python. Это значит, что ничего ставить не нужно. Просто начинаем работать.
# Импортируем всё, что нам нужно, одной строкой
from ipaddress import ip_network, ip_address
Готово! Теперь в нашем арсенале есть два главных инструмента.
Пример 1: Разбираем сеть по косточкам
Допустим, нам дали сеть 192.168.1.0/24. В учебнике просят найти количество адресов, широковещательный адрес и саму маску. Давайте сделаем это на Python.
# Создаем объект сети
network = ip_network('192.168.1.0/24')
# А теперь просто выведем все его свойства
print(f"Вся сеть: {network}")
print(f"Адрес сети: {network.network_address}")
print(f"Широковещательный адрес: {network.broadcast_address}")
print(f"Маска сети: {network.netmask}")
print(f"Количество хостов: {network.num_addresses}")
print(f"Доступные адреса (первые 5): {list(network.hosts())[:5]}") # Покажем только первые 5
Результат в консоли:
Вся сеть: 192.168.1.0/24
Адрес сети: 192.168.1.0
Широковещательный адрес: 192.168.1.255
Маска сети: 255.255.255.0
Количество хостов: 256
Доступные адреса (первые 5): [IPv4Address('192.168.1.1'), IPv4Address('192.168.1.2'), IPv4Address('192.168.1.3'), IPv4Address('192.168.1.4'), IPv4Address('192.168.1.5')]
Видишь? Вместо долгих расчетов мы получили всю информацию одной командой. network.hosts() — это итератор, который возвращает все адреса, которые можно назначить устройствам (исключая адрес сети и широковещательный).
Пример 2: Проверяем, кто в нашей сети
Классическая задача: принадлежит ли адрес 192.168.1.100 сети 192.168.1.0/24? В жизни это нужно, например, чтобы понять, может ли устройство подключиться к локальной сети.
# Наша сеть
our_network = ip_network('192.168.1.0/24')
# Проверяемый адрес
check_ip = ip_address('192.168.1.100')
# Проверка одним оператором 'in'
if check_ip in our_network:
print(f"Адрес {check_ip} принадлежит сети {our_network}")
else:
print(f"Адрес {check_ip} НЕ в сети {our_network}")
Результат:
Адрес 192.168.1.100 принадлежит сети 192.168.1.0/24
А что, если проверить 192.168.2.100?
external_ip = ip_address('192.168.2.100')
print(external_ip in our_network)
Результат: False
Вот и вся магия! Больше не нужно выписывать адреса в двоичном виде и применять побитовое И.
ПРИМЕР 1 ЕГЭ ФИПИ: вычисление маски сети
В терминологии TCP/IP маской сети называют двоичное число, которое показывает, какая часть IP-адреса узла сети относится к адресу сети, а какая — к адресу узла в этой сети. Адрес сети получается в результате применения поразрядной конъюнкции к заданному адресу узла и маске сети. Сеть задана IP-адресом 192.168.32.160 и маской сети 255.255.255.240. Сколько в этой сети IP-адресов, для которых сумма единиц в двоичной записи IP-адреса чётна?
В ответе укажите только число.
Построчное объяснение:
Строка 1: Импорт библиотек
from ipaddress import ip_network, ip_address
- Импортирует из стандартной библиотеки ipaddress два класса:
ip_network - для работы с сетевыми адресами
ip_address - для работы с IP-адресами - В данном коде ip_address не используется, но импортирован для потенциального расширения функционала
Строка 2: Определение IP-адреса
s_ip = "192.168.32.160"
- Создает переменную s_ip типа string
- Присваивает значение "192.168.32.160" - это IP-адрес сети
- Этот адрес является одним из адресов в сети, но не обязательно сетевым адресом
Строка 3: Определение маски сети
ms = "255.255.255.240"
- Создает переменную ms типа string
- Присваивает значение "255.255.255.240" - это маска сети в точечно-десятичной нотации
- Маска 255.255.255.240 соответствует префиксу /28 (28 бит для сети, 4 бита для хостов)
Строка 4: Создание объекта сети
net = ip_network(f"{s_ip}/{ms}")
- Создает объект сети используя f-строку
- f"{s_ip}/{ms}" создает строку "192.168.32.160/255.255.255.240"
- ip_network() автоматически вычисляет правильный сетевой адрес на основе IP и маски
- Для маски 255.255.255.240 сетевой адрес будет 192.168.32.160
Строка 5: Инициализация счетчика
k = 0
- Инициализирует переменную-счетчик k
- Начальное значение 0
- Будет использоваться для подсчета количества адресов с четным количеством единиц в бинарном представлении
Строка 6: Цикл по всем адресам сети
for set in net:
- Цикл for перебирает все возможные IP-адреса в сети
- set - переменная цикла (не рекомендуется использовать имя set, так как это зарезервированное слово в Python)
- net - итерируемый объект, содержащий все адреса сети
- Для сети /28 будет 16 адресов (2⁴ = 16), включая сетевой и широковещательный
Строка 7: Проверка условия четности единиц
if bin(int(set))[2:].count("1") % 2 == 0:
Разберем по частям:
- int(set) - преобразует IP-адрес в целое число (например, 3232243872)
- bin(...) - преобразует число в строку бинарного представления (например, '0b11000000101010000010000010100000')
- [2:] - срез строки, убирает префикс '0b', оставляя только биты
- .count("1") - подсчитывает количество единиц в бинарной строке
- % 2 == 0 - проверяет, четное ли количество единиц
Строка 8: Увеличение счетчика
k += 1
- Инкремент счетчика - увеличивает значение k на 1
- Выполняется только если условие в строке 7 истинно (четное количество единиц)
Строка 9: Вывод результата
print(k)
- Выводит конечное значение счетчика k
- Результат - количество IP-адресов в сети с четным количеством единиц в бинарном представлении
Пример вычислений:
Для сети 192.168.32.160/28 адреса будут:
- 192.168.32.160 (сетевой) - 11000000.10101000.00100000.10100000 → 6 единиц (четное)
- 192.168.32.161 - 11000000.10101000.00100000.10100001 → 7 единиц (нечетное)
- 192.168.32.162 - 11000000.10101000.00100000.10100010 → 7 единиц (нечетное)
- ... и так далее
Практический результат:
Для сети /28 с 16 адресами примерно половина будет иметь четное количество единиц, поэтому ответ будет 8.
Важно: Код считает ВСЕ адреса в сети, включая сетевой и широковещательный!
ПРИМЕР 2 ЕГЭ ФИПИ
В терминологии сетей TCP/IP маской сети называется двоичное число, определяющее, какая часть IP-адреса узла сети относится к адресу сети, а какая — к адресу самого узла в этой сети. Обычно маска записывается по тем же правилам, что и IP-адрес, — в виде четырёх байтов, причём каждый байт записывается в виде десятичного числа. При этом в маске сначала (в старших разрядах) стоят единицы, а затем с некоторого разряда — нули. Адрес сети получается в результате применения поразрядной конъюнкции к заданному IP-адресу узла и маске.
Например, если IP-адрес узла равен 231.32.255.131, а маска равна 255.255.240.0, то адрес сети равен 231.32.240.0.
Для узла с IP-адресом 111.81.27.208 адрес сети равен 111.81.27.192. Чему равно наименьшее возможное значение последнего (самого правого) байта маски? Ответ запишите в виде десятичного числа.
Подробный разбор задачи по вычислению маски сети
Условие задачи
Дано:
- IP-адрес узла: 111.81.27.208
- Адрес сети: 111.81.27.192
- Нужно найти: наименьшее возможное значение последнего байта маски
Теоретическая часть
Что такое маска сети?
Маска сети - это битовая маска, которая определяет, какая часть IP-адреса относится к адресу сети, а какая - к адресу узла.
Как работает вычисление сети?
Адрес сети = IP-адрес AND Маска
Решение задачи
Шаг 1: Переводим в бинарный вид
IP-адрес: 111.81.27.208
В двоичной системе: 01101111.01010001.00011011.11010000
Адрес сети: 111.81.27.192
В двоичной системе: 01101111.01010001.00011011.11000000
Шаг 2: Анализируем последний октет
IP: 11010000 = 208
Сеть: 11000000 = 192
Шаг 3: Определяем возможные маски
Маска должна удовлетворять условию: IP AND Маска = Адрес_сети
Для последнего октета:
208 AND X = 192
Возможные значения последнего байта маски:
192 = 11000000 (2 бита для сети, 6 для узлов)
224 = 11100000 (3 бита для сети, 5 для узлов)
240 = 11110000 (4 бита для сети, 4 для узлов)
248 = 11111000 (5 битов для сети, 3 для узлов)
252 = 11111100 (6 битов для сети, 2 для узлов)
254 = 11111110 (7 битов для сети, 1 для узлов)
255 = 11111111 (8 битов для сети, 0 для узлов)
Шаг 4: Находим наименьшее значение
Наименьшее возможное значение последнего байта маски = 192
Разбор кода
Пояснение работы кода:
- Импорт библиотек: ipaddress предоставляет удобные классы для работы с IP-адресами и сетями.
- Перебор масок: Цикл перебирает все возможные длины префикса от 0 до 32 бит.
- Создание объекта сети: ip_network(f"{u_ip}/{mas}", 0) создает объект сети, где:
u_ip - IP-адрес узла
mas - длина префикса маски
0 - strict=False (разрешает создание сети с адресом, не являющимся сетевым) - Проверка условия: Сравнивает вычисленный адрес сети с заданным.
- Вывод результата: Когда находится подходящая маска, выводится ее значение и цикл прерывается.
Результат выполнения:
Код найдет маску 255.255.255.192, где последний байт = 192.
IP: 111.81.27.208 = 01101111.01010001.00011011.11010000
Маска: 255.255.255.192 = 11111111.11111111.11111111.11000000
AND:
Сеть: 111.81.27.192 = 01101111.01010001.00011011.11000000
ПРИМЕР 3 ФИПИ ЕГЭ Информатика
В терминологии сетей TCP/IP маской сети называют двоичное число, которое показывает, какая часть IP-адреса узла сети относится к адресу сети, а какая — к адресу узла в этой сети. Адрес сети получается в результате применения поразрядной конъюнкции к заданному адресу узла и его маске. Широковещательным адресом называется специализированный адрес, в котором на месте нулей в маске стоят единицы. Адрес сети и широковещательный адрес не могут быть использованы для адресации сетевых устройств.
Сеть задана IP-адресом одного из входящих в неё узлов 191.128.66.83 и сетевой маской 255.192.0.0.
Найдите в данной сети наибольший IP-адрес, который может быть назначен компьютеру. В ответе укажите найденный IP-адрес без разделителей.
Например, если бы найденный адрес был равен 111.22.3.44, то в ответе следовало бы записать: 11122344.
ОТВЕТ: 191191255254
1. Исходные данные
- IP-адрес узла: 191.128.66.83
- Сетевая маска: 255.192.0.0
- Нужно найти наибольший IP-адрес для компьютера в этой сети
2. Анализ маски
Маска 255.192.0.0 в бинарном виде:
text
255.192.0.0 = 11111111.11000000.00000000.00000000
Количество бит маски: 10 бит (8 + 2)
- Сетевой адрес: первые 10 бит фиксированы
- Адрес компьютера: оставшиеся 22 бита
3. Сетевой адрес
text
IP: 191.128.66.83 = 10111111.10000000.01000010.01010011
Маска: 255.192.0.0 = 11111111.11000000.00000000.00000000
AND: = 10111111.10000000.00000000.00000000
Сетевой адрес: 191.128.0.0/10
4. Диапазон адресов
- Минимальный адрес сети: 191.128.0.0
- Максимальный адрес сети: 191.191.255.255
- Широковещательный адрес: 191.191.255.255
- Наибольший адрес компьютера: 191.191.255.254
5. Разбор кода
from ipaddress import ip_network, ip_address
s_ip = "191.128.66.83" # Исходный IP-адрес
ms = "255.192.0.0" # Маска сети
# Создание объекта сети на основе IP и маски
# Аргумент 0 означает strict=False (разрешает host address)
net = list(ip_network(f"{s_ip}/{ms}", 0))
k = 0 # Неиспользуемая переменная
mx = 0 # Неиспользуемая переменная
print(net) # Вывод всех адресов сети
6. Результат выполнения
Код выведет все адреса сети 191.128.0.0/10.
Наибольший адрес для компьютера: 191.191.255.254
7. Форматирование ответа
По условию задачи нужно записать без разделителей:
191.191.255.254 → 191191255254
Ответ: 191191255254
ПРИМЕР 4 ЕГЭ ФИПИ Информатика
В терминологии сетей TCP/IP маской сети называют двоичное число, которое показывает, какая часть IP-адреса узла сети относится к адресу сети, а какая — к адресу узла в этой сети. Адрес сети получается в результате применения поразрядной конъюнкции к заданному адресу узла и маске сети.
Сеть задана IP-адресом 172.16.168.0 и маской сети 255.255.248.0.
Сколько в этой сети IP-адресов, для которых количество единиц в двоичной записи IP-адреса не кратно 5?
В ответе укажите только число.
ОТВЕТ: 1663
from ipaddress import ip_network, ip_address
s_ip="172.16.168.0"
ms="255.255.248.0"
net=ip_network(f"{s_ip}/{ms}",0)
k=0
for s in net:
if bin(int(s))[2:].count("1")%5!=0:
k+=1
print(k)
Построчный разбор
Строка 1: Импорт библиотек
python
from ipaddress import ip_network, ip_address
- ip_network используется для создания объекта, представляющего собой сеть.
- ip_address используется для работы с отдельными IP-адресами (в данном коде явно не используется, но импортирован).
Строка 2-3: Задание начальных условий
python
s_ip="172.16.168.0"
ms="255.255.248.0"
- s_ip — это строка, содержащая IP-адрес сети.
- ms — это строка, содержащая маску сети.
Строка 4: Создание объекта сети
python
net=ip_network(f"{s_ip}/{ms}",0)
- Здесь создается объект сети net.
- f"{s_ip}/{ms}" создает строку в формате "IP-адрес/маска", которую понимает функция ip_network. В данном случае это будет "172.16.168.0/255.255.248.0".
- Аргумент strict=0 (или просто 0) очень важен. По умолчанию strict=True, и функция выдаст ошибку, если адрес сети (172.16.168.0) не является "чистым" (т.е. если биты хостовой части не все нули). В нашем случае 172.16.168.0 действительно не является адресом сети для маски /21 (255.255.248.0), так как 168 в двоичном виде это 10101000, а маска 248 это 11111000, значит биты хостовой части (01000) не нулевые. strict=0 говорит функции проигнорировать это и автоматически вычислить правильный адрес сети (которым будет 172.16.160.0).
Строка 5: Инициализация счетчика
python
k=0
- Создается переменная k, которая будет считать количество IP-адресов, удовлетворяющих условию.
Строка 6: Цикл по всем адресам сети
python
for s in net:
- Объект net является итерируемым. На каждой итерации цикла переменная s будет принимать значение следующего IP-адреса в этой сети. Всего в сети с маской 255.255.248.0 (/21) будет 2^(32-21) = 2^11 = 2048 адресов.
Строка 7: Проверка условия
python
if bin(int(s))[2:].count("1")%5!=0:
Это самая важная строка, которую можно разбить на шаги:
- int(s): IP-адрес s (тип IPv4Address) преобразуется в целое число. Например, адрес 172.16.160.0 будет представлен как большое число.
- bin(...): Это целое число преобразуется в строку, содержащую его двоичное представление. Например, bin(123) вернет строку '0b1111011'.
- [2:]: Это срез строки. Он отрезает первые два символа '0b', оставляя только "чистые" двоичные цифры. Например, '0b1111011'[2:] даст '1111011'.
- .count("1"): Подсчитывает количество единиц в полученной двоичной строке.
- ... %5: Вычисляется остаток от деления количества единиц на 5.
- ... %5 != 0: Условие выполняется, если остаток от деления НЕ равен нулю, то есть если количество единиц не кратно 5.
Строка 8: Увеличение счетчика
python
k+=1
- Если условие в строке 7 истинно (количество единиц не кратно 5), то счетчик k увеличивается на 1.
Строка 9: Вывод результата
python
print(k)
- После того как цикл перебрал все 2048 адресов в сети, выводится итоговое значение счетчика k.
Логика решения
- Определение сети: Программа корректно определяет диапазон адресов сети 172.16.160.0/21 (от 172.16.160.1 до 172.16.167.254, включая широковещательный и адрес сети, если strict=0).
- Перебор адресов: Она перебирает все 2048 адресов в этом диапазоне.
- Анализ каждого адреса: Для каждого адреса она вычисляет, сколько единиц в его двоичном представлении.
- Фильтрация: Адрес учитывается в итоговом счетчике, только если количество единиц в нем не делится нацело на 5.
Таким образом, код прямым перебором находит, что из 2048 адресов сети условию "количество единиц не кратно 5" удовлетворяют ровно 1663 адреса.
ПРИМЕР 5 ЕГЭ ФИПИ ИНФОРМАТИКА
В терминологии сетей TCP/IP маской сети называется двоичное число, определяющее, какая часть IP-адреса узла сети относится к адресу сети, а какая — к адресу самого узла в этой сети. Обычно маска записывается по тем же правилам, что и IP-адрес, — в виде четырёх байтов, причём каждый байт записывается в виде десятичного числа. При этом в маске сначала (в старших разрядах) стоят единицы, а затем с некоторого разряда — нули. Адрес сети получается в результате применения поразрядной конъюнкции к заданным IP-адресу узла и маске.
Например, если IP-адрес узла равен 231.32.255.131, а маска равна 255.255.240.0, то адрес сети равен 231.32.240.0.
Для узла с IP-адресом 117.73.208.27 адрес сети равен 117.73.192.0. Каково наименьшее возможное количество нулей в разрядах маски?
Ответ: 13
from ipaddress import ip_network, ip_address
s_ip="117.73.192.0"
u_ip="117.73.208.27"
mn=100000
for ms in range(33):
net=ip_network(f"{u_ip}/{ms}",0)
if str(net)==f"{s_ip}/{ms}":
k=bin(int(net.netmask))[2:].count("0")
mn=min(mn,k)
print(mn)
13 задание ЕГЭ Информатика: Задачи для отработки
Задача 1
Если маска подсети 255.255.255.240 и IP-адрес компьютера в сети 10.10.10.25, то порядковый номер компьютера в сети равен _____.
Ответ: 9
Задача 2
Для узла с IP-адресом 145.92.210.44 адрес сети равен 145.92.192.0. Каково наименьшее возможное количество нулей в разрядах маски?
Ответ: 10
Задача 3
Для узла с IP-адресом 201.15.170.33 адрес сети равен 201.15.160.0. Каково наименьшее возможное количество нулей в разрядах маски?
Ответ: 11
Задача 4
Для узла с IP-адресом 95.157.88.244 адрес сети равен 95.157.80.0. Каково наименьшее возможное количество нулей в разрядах маски?
Ответ: 12
Задача 4
Для узла с IP-адресом 180.92.112.18 адрес сети равен 180.92.96.0. Каково наименьшее возможное количество нулей в разрядах маски?
Ответ: 11
Задача 5
Для узла с IP-адресом 222.111.64.100 адрес сети равен 222.111.64.0. Каково наименьшее возможное количество нулей в разрядах маски?
Ответ: 8
#Python #IPадреса #СетевыеТехнологии #РазборКода #Программирование
#Алгоритмы #ОбучениеPython #ПримерыКода #ipaddress #МаскаСети #ДвоичнаяСистема #БитовыеОперации #PythonProgramming #СетевыеРасчеты #ipaddress #МаскаСети #ДвоичнаяСистема #БитовыеОперации #PythonProgramming #СетевыеРасчеты #ЗадачиПоПрограммированию #PythonДляНачинающих #РазборЗадач #ПрактикаPython #СетиДляПрограммистов