4

我有一个需要转换为 CIDR 表示法的 ipaddress/mask 列表。

例如 12.174.36.240/24 需要转换为 12.174.36.0/24 或类似http://www.subnet-calculator.com/cidr.php 的东西

如何实现?

PS:掩码值并不总是24。

4

2 回答 2

3

所以基本上 IPV4 地址和网络掩码是 32 位无符号整数,以 8 位对显示,它们之间有一个点。

所以如果你有“abcd”你可以通过做得到整数值

(a<<24) + (b<<16) + (c<<8) + d 

如果您不习惯 << 它会将数字中的位向左移动作为右参数的次数。因此a<<ba*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 位簇,以十六进制显示,它们之间用逗号分隔,并带有一些用于多次运行 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::

我想在此基础上,您可以创建一个功能来满足您的需求。

于 2013-12-13T22:10:46.290 回答
2

为了引导您朝着正确的方向前进,请考虑一下 IPv4 地址是什么(一个 32 位整数)。现在,考虑什么是掩码(按位运算中使用的位字段)。

在大端系统上获取地址 127.0.0.1。在十六进制中,即0x7f000001. 24 位掩码是0xffffff00(1 的 24 位,0 的 8 位,总共 32 位)。地址和掩码的按位与0x7f000001 & 0xffffff00 = 0x7f000000是 CIDR 格式。

我把它留给你来确定如何最好地解析地址,将 IPv4 地址转换为整数形式(并返回),并从路由前缀掩码创建位掩码,尽管我会告诉你有标准函数至少地址操作。

于 2013-12-13T18:12:15.830 回答