【发布时间】:2014-01-01 14:14:53
【问题描述】:
我有一个需要转换为 CIDR 表示法的 ipaddress/mask 列表。
例如12.174.36.240/24需要转换成12.174.36.0/24 或类似http://www.subnet-calculator.com/cidr.php 所做的事情
如何做到这一点?
PS:掩码值并不总是24。
【问题讨论】:
标签: c++ ip-address subnet cidr
我有一个需要转换为 CIDR 表示法的 ipaddress/mask 列表。
例如12.174.36.240/24需要转换成12.174.36.0/24 或类似http://www.subnet-calculator.com/cidr.php 所做的事情
如何做到这一点?
PS:掩码值并不总是24。
【问题讨论】:
标签: c++ ip-address subnet cidr
所以基本上 IPV4 地址和网络掩码是 32 位无符号整数,以 8 位成对显示,它们之间有一个点。
所以如果你有“a.b.c.d”,你可以通过做得到整数值
(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&,您将得到 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::
我想在此基础上,您可以创建一个功能来满足您的需求。
【讨论】:
为了引导您走向正确的方向,请考虑一下 IPv4 地址是什么(一个 32 位整数)。现在,考虑一下掩码是什么(按位运算中使用的位域)。
在大端系统上获取地址 127.0.0.1。在十六进制中,即0x7f000001。 24 位掩码是0xffffff00(24 位 1,8 位 0,总共 32 位)。地址和掩码0x7f000001 & 0xffffff00 = 0x7f000000的位与是CIDR格式。
我留给你来决定如何最好地解析地址,将 IPv4 地址转换为整数形式(并返回),并从路由前缀掩码创建位掩码,但我会告诉你有标准的至少用于地址操作的函数。
【讨论】: