ГлавнаяБлогVLSM-калькулятор: алгоритм разбиения подсетей на Python
Алгоритмы

VLSM-калькулятор: алгоритм разбиения подсетей на Python

Реализация VLSM (Variable Length Subnet Mask) на Python: сортировка подсетей по убыванию, выравнивание по границам и обработка переполнения. Попробуйте код!

Al
Редакция Algolitalgolit.ru
6 мин чтения19 июля 2026 г.

Что такое VLSM и зачем он нужен?

При планировании сети часто требуется разделить блок CIDR на подсети разного размера. Например, головному офису нужно 100 адресов, филиалу А — 50, филиалу Б — 25, а DMZ — 10. Если делить на равные части, адреса будут расходоваться неэффективно. VLSM (Variable Length Subnet Masking) позволяет выделять каждой подсети свою маску, минимизируя потери. В этой статье мы разберём алгоритм, который лежит в основе VLSM-калькулятора.

Что нужно вычислить?

Для каждой подсети в VLSM-плане требуется:

  • Минимальная длина префикса (маска подсети), вмещающая заданное количество хостов.
  • Начальный адрес внутри родительской сети, не пересекающийся с другими подсетями.

Первая задача решается простой формулой. Вторая — сортировкой требований по убыванию и последовательной упаковкой в адресное пространство.

Вычисление количества бит для хостов

В IPv4 количество полезных хостов в подсети = общее количество адресов минус 2 (адрес сети и широковещательный адрес). Нужно найти наименьшее n (биты хостов) такое, что 2^n - 2 >= запрошенных хостов.

import math

def ceil_log2(x):
    return math.ceil(math.log2(x))

def vlsm_host_bits(hosts):
    host_bits = ceil_log2(hosts + 2)
    subnet_prefix = 32 - host_bits
    subnet_size = 2 ** host_bits
    return host_bits, subnet_prefix, subnet_size

Передача hosts + 2 в ceil_log2 сразу учитывает вычет адреса сети и широковещательного адреса, не требуя отдельной обработки.

Жадная упаковка: крупные подсети — первыми

Стандартный подход для VLSM — размещать сначала самые крупные подсети. Если упаковывать от меньших к большим, после размещения крупной подсети могут остаться фрагменты, не кратные её размеру, что приведёт к потере адресов.

def calculate_vlsm(network_num, prefix, parent_total, requirements):
    # Сортируем требования по убыванию
    sorted_reqs = sorted(requirements, reverse=True)
    current_num = network_num
    subnets = []

    for hosts in sorted_reqs:
        host_bits, subnet_prefix, subnet_size = vlsm_host_bits(hosts)
        # Выравнивание по границе подсети
        aligned_num = ((current_num + subnet_size - 1) // subnet_size) * subnet_size
        if aligned_num + subnet_size - 1 > network_num + parent_total - 1:
            raise ValueError("Подсети не помещаются в родительскую сеть")
        broadcast_num = aligned_num + subnet_size - 1
        subnets.append({
            'network': num_to_ip(aligned_num),
            'mask': prefix_to_mask(subnet_prefix),
            'broadcast': num_to_ip(broadcast_num),
            'first_host': num_to_ip(aligned_num + 1),
            'last_host': num_to_ip(broadcast_num - 1),
            'usable_hosts': subnet_size - 2,
            'total_addresses': subnet_size,
            'prefix': subnet_prefix
        })
        current_num = aligned_num + subnet_size
    return subnets

Выравнивание по границе подсети

Подсети CIDR могут начинаться только с адреса, кратного их размеру. Например, /23 (512 адресов) может начинаться только с адреса, делящегося на 512. Следующая строка находит ближайшую допустимую границу:

aligned_num = ((current_num + subnet_size - 1) // subnet_size) * subnet_size

Деление current_num (адрес сразу после предыдущей подсети) на subnet_size, округление вверх и умножение обратно даёт ближайший выровненный адрес, не меньший current_num.

Обработка переполнения: жёсткая ошибка

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

if aligned_num + subnet_size - 1 > network_num + parent_total - 1:
    raise ValueError("Подсети не помещаются в родительскую сеть")

Выравнивание по границам создаёт зазоры, поэтому даже если сумма хостов меньше общего числа адресов, план может не поместиться. Явная ошибка позволяет сразу понять, что требования несовместимы.

Практический вывод

Алгоритм VLSM несложен, но важно правильно реализовать три вещи: сортировку по убыванию, выравнивание по границам и явное сообщение об ошибке при переполнении. Попробуйте написать свою реализацию на Python и протестируйте на разных наборах требований. Если хотите увидеть готовый инструмент, загляните в Torinoa Subnet Calculator.

#VLSM#подсети#CIDR#алгоритмы#сети
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →