Продолжаем осваивать побитовые сдвиги на примере расчета маски подсети. Возможно, вы никогда не слышали ни о какой маске, кроме венецианской, но маску подсети ваше устройство использует прямо сейчас.
Маска подсети - это значение, используемое в сетях для определения того, какая часть IP-адреса представляет собой сетевой адрес, а какая - адрес хоста. Это 32-битное значение, которое обычно выражается в точечной десятичной системе счисления, где каждый 8-битный сегмент (или "октет") представляет собой двоичное значение от 0 до 255.
По сути, маска подсети используется для разделения IP-адреса на сетевую часть и часть хоста. Сетевая часть идентифицирует сеть, к которой принадлежит устройство, а хост-часть идентифицирует конкретное устройство в этой сети.
Например, в сети с маской подсети 255.255.255.0 (также известной как префикс /24) первые три октета IP-адреса будут представлять сетевую часть, а последний октет - хостовую часть. Это означает, что все устройства с IP-адресами, которые имеют одинаковые первые три октета, находятся в одной сети и могут напрямую общаться друг с другом.
Маски подсетей необходимы, поскольку они позволяют сетевым администраторам делить большие диапазоны IP-адресов на более мелкие, более управляемые подсети. Это может помочь уменьшить перегрузку сети, повысить безопасность за счет разделения различных типов устройств на отдельные подсети и упростить управление сетевыми ресурсами.
В дополнение к маскам подсети, нотация CIDR (Classless Inter-Domain Routing) является еще одним широко используемым методом определения размера сети. Нотация CIDR использует длину префикса для указания количества битов в сетевой части IP-адреса и часто используется как взаимозаменяемая сущность с масками подсетей, особенно часто в сетевом оборудовании корпоративного класса.
Рассмотрим программу. Возьмем в качестве примера пожалуй самый популярный префикс длиной 24 бита и вычислим соответствующую маску подсети.
Справочная информация по другим префиксам дана в коде программы в качестве комментария.
Длина префикса преобразуется в двоичную строку из 24 единиц с помощью strings.Repeat("1", prefixLength), strings.Repeat повторяет единицу 24 раза, а затем разбираем в int64 с помощью strconv.ParseInt(). Это дает нам значение с 24 единицами в крайних левых битах и нулями в крайних правых битах.
Затем мы сдвигаем это значение влево на 32 бита длины префикса, чтобы заполнить крайние правые биты нулями, и преобразуем результат в тип данных uint32. Это дает нам маску подсети в двоичном виде, которую мы затем печатаем в точечной десятичной нотации, используя серию побитовых сдвигов и операций маскирования для извлечения каждого октета.