Как рассчитать диапазон IP-адресов, если указаны IP-адрес и маска сети?
Когда IP-диапазон записывается как aaa.bbb.ccc.ddd/netmask ( нотация CIDR), мне нужно вычислить первый и последний включенный IP-адрес в этом диапазоне с помощью C#.
Пример:
Ввод: 192.168.0.1/25
Результат: 192.168.0.1 - 192.168.0.126
8 ответов
У моего хорошего друга Алессандро есть хороший пост, касающийся битовых операторов в C#, вы должны прочитать об этом, чтобы знать, что делать.
Это довольно легко. Если вы разбиваете IP-адрес на двоичный, сетевой адрес - это IP-адрес, где все биты хоста (0 в маске подсети) равны 0, а последний адрес, широковещательный адрес, - это место, где все хосты биты равны 1.
Например:
ip 192.168.33.72 mask 255.255.255.192
11111111.11111111.11111111.11000000 (subnet mask)
11000000.10101000.00100001.01001000 (ip address)
Части, выделенные полужирным шрифтом, являются битами HOST (остальные являются битами сети). Если вы установите все биты хоста на 0 на IP, вы получите первый возможный IP:
11000000.10101000.00100001.01000000 (192.168.33.64)
Если вы установите все биты хоста в 1, то вы получите последний возможный IP (он же широковещательный адрес):
11000000.10101000.00100001.01111111 (192.168.33.127)
Итак, для моего примера:
the network is "192.168.33.64/26":
Network address: 192.168.33.64
First usable: 192.168.33.65 (you can use the network address, but generally this is considered bad practice)
Last useable: 192.168.33.126
Broadcast address: 192.168.33.127
Я просто выложу код:
IPAddress ip = new IPAddress(new byte[] { 192, 168, 0, 1 });
int bits = 25;
uint mask = ~(uint.MaxValue >> bits);
// Convert the IP address to bytes.
byte[] ipBytes = ip.GetAddressBytes();
// BitConverter gives bytes in opposite order to GetAddressBytes().
byte[] maskBytes = BitConverter.GetBytes(mask).Reverse().ToArray();
byte[] startIPBytes = new byte[ipBytes.Length];
byte[] endIPBytes = new byte[ipBytes.Length];
// Calculate the bytes of the start and end IP addresses.
for (int i = 0; i < ipBytes.Length; i++)
{
startIPBytes[i] = (byte)(ipBytes[i] & maskBytes[i]);
endIPBytes[i] = (byte)(ipBytes[i] | ~maskBytes[i]);
}
// Convert the bytes to IP addresses.
IPAddress startIP = new IPAddress(startIPBytes);
IPAddress endIP = new IPAddress(endIPBytes);
Я бы порекомендовал использовать библиотеку IPNetwork https://github.com/lduchosal/ipnetwork. Начиная с версии 2 он также поддерживает IPv4 и IPv6.
IPv4
IPNetwork ipnetwork = IPNetwork.Parse("192.168.0.1/25");
Console.WriteLine("Network : {0}", ipnetwork.Network);
Console.WriteLine("Netmask : {0}", ipnetwork.Netmask);
Console.WriteLine("Broadcast : {0}", ipnetwork.Broadcast);
Console.WriteLine("FirstUsable : {0}", ipnetwork.FirstUsable);
Console.WriteLine("LastUsable : {0}", ipnetwork.LastUsable);
Console.WriteLine("Usable : {0}", ipnetwork.Usable);
Console.WriteLine("Cidr : {0}", ipnetwork.Cidr);
Выход
Network : 192.168.0.0
Netmask : 255.255.255.128
Broadcast : 192.168.0.127
FirstUsable : 192.168.0.1
LastUsable : 192.168.0.126
Usable : 126
Cidr : 25
Повеселись!
Инвертировать маску (XOR с единицами), И это с IP. Добавьте 1. Это будет начальный диапазон. ИЛИ IP с маской. Это будет конечный диапазон.
Я узнал этот ярлык, работая на позиции развертывания сети. Это мне очень помогло, я решил поделиться этим секретом со всеми. До сих пор я не смог найти более простой способ в Интернете, о котором я знаю.
Например сеть 192.115.103.64 /27, какой диапазон?
просто помните, что маска подсети 0, 128, 192, 224, 240, 248, 252, 254, 255
255.255.255.255 11111111.11111111.11111111.11111111 / 32
255.255.255.254 11111111.11111111.11111111.11111110 / 31
255.255.255.252 11111111.11111111.11111111.11111100 / 30
255.255.255.248 11111111.11111111.11111111.11111000 / 29
255.255.255.240 11111111.11111111.11111111.11110000 / 28
255.255.255.224 11111111.11111111.11111111.11100000 / 27
255.255.255.192 11111111.11111111.11111111.11000000 / 26
255.255.255.128 11111111.11111111.11111111.10000000 / 25
255.255.255.0 11111111.11111111.11111111.00000000 / 24
из / 27 мы знаем, что (11111111.11111111.11111111.11100000). Считая слева, это третье число из последнего октета, которое равно 255.255.255.224 маске подсети. (Не считайте 0, 0 - это / 24), поэтому 128, 192, 224 и т. Д.
Здесь, где математика входит:
используйте маску подсети - в этом случае маску подсети из предыдущей маски подсети 224-192=32
Мы знаем, что 192.115.103.64 это сеть: 64 + 32 = 96 (следующая сеть для /27)
что означает, что у нас есть.0 .32. 64. 96. 128. 160. 192. 224. (Не могу использовать 256, потому что это.255)
Вот диапазон 64 - 96.
сеть 64.
первый хост 65.(первая сеть +1)
Последний хозяин 94. (трансляция -1)
трансляция 95. (последняя сеть -1)
Входные данные: 192.168.0.1/25
Маска это часть: /25
Чтобы найти сетевой адрес, сделайте следующее:
Вычтите маску из длины ip (32 - маска) = 32 - 25 = 7 и возьмите эти биты справа
В данном ip-адресе т.е.
192.168.0.1
в двоичном виде это:11111111 11111111 00000000 00000001
Теперь, взяв 7 бит справа "0"1111111 11111111 00000000 00000000
Который в десятичном виде:192.168.0.0
(это сетевой адрес)
Чтобы найти первый действительный / используемый IP-адрес, добавьте +1 к сетевому адресу, т.е. 192.168.0.1
Чтобы найти последний / широковещательный адрес, процедура такая же, как и при поиске сетевого адреса, но здесь вы должны сделать (32-маску) биты справа от '1'
То есть: 11111111 11111111 00000000 01111111
Который в десятичном виде 192.168.0.127
Чтобы найти последний действительный / используемый IP-адрес, вычтите 1 из широковещательного адреса, т.е. 192.168.0.126
Я знаю, что это старый вопрос, но я нашел эту изящную библиотеку на nuget, которая, кажется, помогает мне:
Возможно, вы уже знаете это, но чтобы убедиться, что вы все правильно поняли, загляните на http://www.subnet-calculator.com/ - вы можете увидеть, как биты представляют сетевую и хостовую части адреса.,