Таким образом, в основном IPV4-адрес и сетевая маска представляют собой 32-разрядное целое число без знака, отображаемое парами 8 бит с точкой между ними.
Так что если у вас есть «ABCD» вы можете получить целое значение, делая
(a<<24) + (b<<16) + (c<<8) + d
Если вы не привыкли к < < это сдвигают биты числа к левому количеству раз как правильный аргумент. Таким образом, a<<b
- это то же самое, что и a*2^b
Теперь в CIDR число после косой черты указывает, сколько бит (из 32) является сетевой частью числа перед косой чертой. например. 10.10.10.1/28 имеет 28-битную сеть и 32-28 = 4-разрядную часть хоста. Это означает, что если вы берете ip и переводите его на число (= 0x0A0A0A01) и делаете логическое &
с 0xFFFFFFFF < < 4 (= 0xFFFFFFF0), вы получаете 0x0A0A0A00. Если вы переводите это на ip-адрес со следующим:
sprintf("%d.%d.%d.%d", (n>>24)&0xff, (n>>16)&0xff, (n>>8)&0xff, n&0xff)
Вы получаете 10.10.10.0. Кроме того, если вы переводите 0xFFFFFFF0 в ip с тем же алгоритмом, вы получите 255.255.255.248, который является маской сети, которая соответствует длине маски 28.
IPv6 точно такой же, кроме 128 бит, разделенных на 8 16-разрядных кластеров, отображаемых в hex с запятыми между ними с некоторым причудливым ярлыком для нескольких прогонов 0 (: :) ..
например.
fe80::52e5:49ff:ffc9:1889/64 ==
;;convert the mask
0xffffffffffffffffffffffffffffffff << (128-64) =
0xffffffffffffffff0000000000000000
;;convert the ip:
fe80::52e5:49ff:ffc9:1889 ==
fe80:0000:0000:0000:52e5:49ff:ffc9:1889 ==
0xfe8000000000000052e549ffffc91889
0xfe8000000000000052e549ffffc91889
& 0xffffffffffffffff0000000000000000
= 0xfe800000000000000000000000000000
;;convert first address in range back to string:
fe80:0000:0000:0000:0000:0000:0000:0000 =
fe80::
Я думаю, что на основе этого вы можете сделать функцию, которая делает то, что вы хотите.
http://stackoverflow.com/questions/6657475/netmask-conversion-to-cidr-format-in-c –