我有一个ipaddress / mask列表,需要转换为CIDR表示法。
例如12.174.36.240/24需要转换为12.174.36.0/24 或类似http://www.subnet-calculator.com/cidr.php所做的事情
如何实现这一目标?
PS:掩码值并不总是24。
答案 0 :(得分:2)
为了引导您朝着正确的方向前进,请考虑IPv4地址是什么(32位整数)。现在,考虑一下掩码是什么(按位运算中使用的位字段)。
在big-endian系统上获取地址127.0.0.1。在十六进制中,那是0x7f000001
。 24位掩码是0xffffff00
(24位,1位,8位,0位,32位)。按位和地址以及掩码0x7f000001 & 0xffffff00 = 0x7f000000
是CIDR格式。
我留给你确定如何最好地解析地址,将IPv4地址转换为整数形式(和返回),并从路由前缀掩码创建一个位掩码,但我会告诉你有标准至少用于地址操作的函数。
答案 1 :(得分:2)
所以基本上IPV4地址和网络掩码是32位无符号整数,以8位对的形式显示,它们之间有一个点。
因此,如果你有“a.b.c.d”,你可以通过
获得整数值(a<<24) + (b<<16) + (c<<8) + d
如果你不习惯&lt;&lt;它将数字中的位向左移动作为右参数的次数。因此a<<b
与a*2^b
相同
现在在CIDR中,斜杠后面的数字告诉你在斜杠之前的数字的网络部分有多少位(32位)。例如。 10.10.10.1/28具有28位网络和32-28 = 4位主机部分。这意味着如果你取ip并将其转换为数字(= 0x0A0A0A01)并使用0xFFFFFFFF&lt;&lt; 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位集群,以十六进制显示,它们之间有逗号,多个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::
我想在此基础上你可以制作出你想要的功能。