将IP地址转换为整数

9
我如何将具有以下形式的IP地址转换为整数:A.B.或A.B.C.*或A..*或. 我想编写一个C程序,可以确定IP地址是否是另一个IP地址的子集。例如,IP地址192.168.125.5是192.168.的子集。现在我想将两个IP地址都转换为唯一的整数,随后检查一个是否是另一个的子集。有办法实现这一点吗?

你根本不想将IP地址转换为整数。首先,这仅适用于IPv4。你需要将它们转换为适当长度的字节数组,然后对它们进行网络掩码操作。 - user207421
2
如果你的平台支持,可以使用 inet_pton() - Jasen
4个回答

17

您想要确定一个IP地址是否在子网中,并且为此,您想要应用网络掩码。很可能(肯定)已经有现成的库可以实现您想要的功能。如果您想要自行开发,请参考以下内容。

如果此IP地址来自可信源(即不是用户),则可以通过执行以下操作从标准C字符串中提取IP地址:

char ipAddressString[16] = "192.168.125.5"
char netMaskString[16] = "255.255.0.0"
char subnetString[16] = "192.168.0.0"

uint32_t ipAddress = parseIPV4string(ipAddressString);
uint32_t netmask = parseIPV4string(netmaskString);
uint32_t subnet = parseIPV4string(subnetString);

if (ipAddress & netmask == subnet) {
  return true;
}

uint32_t parseIPV4string(char* ipAddress) {
  char ipbytes[4];
  sscanf(ipAddress, "%uhh.%uhh.%uhh.%uhh", &ipbytes[3], &ipbytes[2], &ipbytes[1], &ipbytes[0]);
  return ipbytes[0] | ipbytes[1] << 8 | ipbytes[2] << 16 | ipbytes[3] << 24;
}

很好,谢谢你提供的解析器逻辑! - Derek Dowling
1
将一个整数(%d)读入到字符指针(ipbytes[x])中会导致严重的错误,因为sscanf会向ipbytes[x]指向的内存写入sizeof(int)字节。这个例子非常危险。 - Zac
2
@Zac 真尴尬!我已经修复了这个错误。 - OmnipotentEntity

15

一个IP地址,例如192.168.0.1可以通过将其以十六进制写成整数,如0xC0 0xA8 0x00 0x01或0xC0A80001。

然后只需进行位匹配,因此您可以构建相应的子网掩码,即255.255.0.0,它只是0xFFFF0000,您可以通过执行以下操作测试两者是否匹配:

0xC0A80001 & 0xFFFF0000 == 0xC0A80000 & 0xFFFF0000

在等式测试中,一个方面是“您关心的基本内容”,另一个方面是具有给定掩码的实际地址。

通常可以通过将“*”设置为0并将实际数字设置为0xFF来构造适当的掩码,如果您想要更细粒度的掩码,则使用“*”很难表达。


1

简单而不普遍的方法是使用sscanf(带有int a,b,c,d):

sscanf(ip,"%d.%d.%d.%d",&a,&b,&c,&d);

但仅在您拥有所有部分的ip时才有效:10.47.100.1

如果不是这种情况,则仍然可以使用sscanf的返回值,该值将告诉您成功找到多少匹配项(或EOF)。

在获得4个数字后,您可以检查子集关系。


不,我想将IP地址转换为整数,然后检查子集关系... - mmuttam
你仍然可以从你得到的4个数字构造一个整数。困难的部分是解析整数。之后,你可以像其他人在这里建议的那样将它们向左移动。 - Israel Unterman

0
一个单独的整数(假设32位)无法足够表示您正在概述的内容。您需要更多信息才能表达星号。
例如,您可以有一对(地址、网络掩码),其中网络掩码可能是一个小整数,代表有效高位比特的数量,因此例如像“10.0.0.0”这样的网络地址可以由一对(0x0a000000,8)表示。如果您真的想要在某些原因下在地址中随意使用通配符,则需要一个完整的每个地址位标志位集合,因此需要两个32位整数。然后,您可以将类似于“192.168.”的东西表示为一对(0xc0a80000, 0xffff0000)。

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