如何使用C++将IP地址/子网掩码转换为CIDR?

4
我有一个IP地址/掩码列表,需要转换为CIDR表示法。
例如,12.174.36.240/24需要转换为12.174.36.0/24,或者类似于http://www.subnet-calculator.com/cidr.php所做的内容。
如何实现这一点?
附注:掩码值不总是24。

https://dev59.com/GFnUa4cB1Zd3GeqPXiKT - Luca Davanzo
2个回答

4

基本上,IPV4地址和子网掩码是32位无符号整数,以8位一组显示,并在它们之间用点分隔。

因此,如果您有“a.b.c.d”,则可以通过执行以下操作来获取整数值

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

如果您不熟悉 " << ",它将数字中的位向左移动与右参数相同的次数。因此,a<
现在,在 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::

我想你可以根据这个做一个函数,实现你需要的功能。

1
谢谢。我在网络上找到了一个类似的方法。但是我正在寻找一些标准的C++库,能够执行类似的任务?我猜没有,因此将不得不为此设计自己的函数。完成后会发布代码。 - chingupt

2

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

以大端系统上的127.0.0.1地址为例。以十六进制表示,那是0x7f000001。24位掩码是0xffffff00(24位为1,8位为0,总共32位)。地址与掩码进行按位与0x7f000001 & 0xffffff00 = 0x7f000000就是CIDR格式。

我让你自行确定如何最好地解析地址,将IPv4地址转换为其整数形式(以及反向转换),并从路由前缀掩码创建位掩码,尽管我会告诉您至少有用于地址操作的标准函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接