9

可能重复:
IP 地址到整数 - C

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

4

4 回答 4

15

您需要确定 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;
}
于 2012-04-23T15:54:35.720 回答
13

一个 IP 地址,例如 192.168.0.1 可以很容易地写成一个整数,只需用十六进制写成 0xC0 0xA8 0x00 0x01 或只是 0xC0A80001

那么这只是位匹配的情况,因此您构造了一个相应的子网掩码 255.255.0.0 ,它只是 0xFFFF0000 ,您可以通过以下方式测试两者是否匹配:

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

其中平等测试的一侧是“您关心的基本内容”,另一侧是真实地址,给定的掩码在两侧都是相同的。

一般来说,您可以通过将“*”设置为 0 并将实际数字设置为 0xFF 来构建合适的掩码,如果您想要更细粒度的掩码,则很难用“*”表示。

于 2012-04-23T15:47:35.993 回答
1

简单且非通用的方法是使用 sscanf (with int a, b, c, d): sscanf(ip, "%d.%d.%d.%d", &a, &b, &c, &d); 但它仅在您拥有所有部分的 ip 时才有效:10.47.100.1

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

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

于 2012-04-23T15:45:18.373 回答
0

单个整数(假设为 32 位)不足以表示您所概述的内容。您需要更多信息才能表达星号。

例如,您可以有一对(地址,网络掩码),其中网络掩码是一个小整数,表示有效高位的数量,因此例如“10.0.0.0”之类的网络地址可能是由对 (0x0a000000, 8) 表示。如果出于某种原因您真的希望能够在地址中的“任何地方”使用通配符,则每个地址位需要一个完整的标志位,因此需要两个 32 位整数。然后您可以将“192.168 .. ”之类的东西表示为对(0xc0a80000,0xffff0000)。

于 2012-04-23T15:46:33.717 回答