验证IP和CIDR组合

3

我有一个用户提交的带有子网掩码的IP地址,我需要确保它是有效的。例如,如果用户提交:10.113.0.0/14,我需要将其标记为无效,因为该IP范围的/14块始于10.112.0.0。

我如何在PHP中实现这个功能?


为什么它是无效的?10.112.0.0 /14具有从10.112.0.0到10.115.255.255的地址。 - dbasnett
正确,但是10.113.0.0没有14位的CIDR,因为这将意味着它有262,142个可用地址。那将超出10.115.255.255的范围。10.133.0.0有65,534个可用地址,因此它是/16。 - Kristopher
1
10.113.0.0/14是10.112.0.0/14网络中的有效地址。10.115.254.1/14也是如此。我认为你在问一个不同的问题。 - dbasnett
我没有问如何验证10.113.0.0是否在10.112.0.0/14网络中。我认为你正在回答一个不同的问题。我知道这个:在postgresql中运行此查询:select '10.113.0.0/14'::cidr。它会出现错误:ERROR: invalid cidr value: "10.113.0.0/14" DETAIL: 值在掩码右侧设置了位。 - Kristopher
你想要回答的问题是:如何确定一个IP地址和CIDR对是否表示一个有效的网络IP地址和CIDR对。要做到这一点,可以将IP地址和CIDR转换为数字,进行按位与运算,然后判断结果是否与给定的IP地址相匹配。 - dbasnett
以上并不总是适用的。比如给定的值是192.168.10.0/26。子网掩码有26位处于开启状态,而IP地址在最后4位上没有位处于开启状态。按位与运算的结果将会得到相同的IP地址。 - Adil
3个回答

2

我有同样的问题,所以在这里分享我的结果:

$ipLong = ip2long($ip);
if ( ( ($ipLong << $prefix) ^ 0) == true ) {
    //IP and prefix pair is not valid
}

解释

让我们来评估255.255.0.0/16。

对于IP 255.255.0.0,长整型的二进制表示为10000000000000000。

  1. $ipLong << $prefix 左移16位以删除所有网络ID位。
  2. ^ 0 在上一步操作后,检查是否存在任何设置的位。
  3. 对于有效的IP和前缀,所有位都必须未设置,因此如果结果为true,则表示无效。

这对我没有用,你能详细解释一下你的答案吗? - Salem
IP的二进制表示形式类似于10101010000。"/4"表示您应该向左移动多少个字节:1010101---0000。在有效IP进行移位后,您应该只剩下所有的零。为了实现这一点,您可以运行"^ 0"。 - terales

0

0

这不完全是我想要的,但它确实给了我所需的数学内容。谢谢。 - Kristopher
3
请问能否提供您的结果函数? - Patrick

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