如何使用 PHP 简化 IP 地址?尝试 long2ip(ip2long(地址))
How can I simplify an IP address using PHP? Trying long2ip(ip2long(address))
我的系统包括一个存储 IP 地址并将它们与从我的 Web 界面发送的值进行比较的第三方盒子。我遇到一个问题,用户为第三方盒子输入的网络掩码为 255.255.255.000,而盒子将其存储为 255.255.255.0。然而,下次盒子重新启动并被告知掩码包含 000 时,它断定这些值不同并更新其数据库并重新启动。并重新启动。并重新启动。
我的目的是通过将网络掩码以简化形式 255.255.255.0 存储在我自己的系统中来解决这个问题(另一个例子是将 010.001.002.005 存储为 10.1.2.5)。但我是 PHP 的新手。我尝试使用代码 $mask = long2ip(ip2long($mask))
将条目转换为标准化形式,但只返回 0.0.0.0。我需要做些什么来将 IP 转换为 long 和 back 吗?有没有更好的方法来简化这个?
ip2long
returns false 错误,它似乎没有检测到 000 为有效。由于 255.255.255.000
未被检测为有效 IP,它将 return 为假,因此 long2ip(false)
不会吐出有效 IP。
您甚至可以在接受 IP 地址之前检查 ip2long(input)
return 是否正确。进行适当的验证可以防止无效的 IP 破坏系统。尝试对所有可能的无效 IP 地址实施自动更正将比仅强制执行一个有效的 IP 地址要困难得多。
按照评论中@ka_lin 的建议,只需将其分解成多个部分,将其转换为一个 int,它将删除前导 0 并使用 implode 重建它...
$mask = implode(".", array_map("intval", explode(".", $mask)));
一个简单且开销较少的版本假定 IP 地址由 4 个部分组成...
list ($o1, $o2, $o3, $o4) = explode(".", $mask);
$mask = (int)$o1.".".(int)$o2.".".(int)$o3.".".(int)$o4;
这很难,因为 010.001.002.005 是一个有效的 IP 地址,但也可能令人困惑(有时以 0 开头的数字是八进制的)。
注意:ip2long()
有一个问题:它不接受有效的 IP 地址 127.1
(经典的表示法,但有效!)或 127.0.0.010
(RFC 表示无效,但大多数人将 010
读作八进制数)。
gethostbyname()
的备选方案。但是 gethostbyname()
也有问题:如果输入了无效的 ip(如 127.0.0.1234
),它会进行 DNS 查找和 returns 源,如果查找失败。
解决方案可以是:
long2ip(ip2long(gethostbyname($IP_ADDRESS)))
我个人的解决方案是以下功能:
function aton ( $addr )
{
$l = explode('.',$addr);
switch (count($l))
{
case 0: return FALSE;
case 1: return intval($l[0]) & 0xffffffff;
case 2: return ( intval($l[0]) << 24
| intval($l[1])
) & 0xffffffff;
case 3: return ( intval($l[0]) << 24
| intval($l[1]) << 16
| intval($l[2])
) & 0xffffffff;
default: return ( intval($l[0]) << 24
| intval($l[1]) << 16
| intval($l[2]) << 8
| intval($l[3])
) & 0xffffffff;
}
}
有了这个功能,您可以使用:
long2ip(aton($IP_ADDRESS))
顺便说一句,我从来没有遇到过像 255.255.255.0
.
这样的特殊 IP 地址的问题
我的系统包括一个存储 IP 地址并将它们与从我的 Web 界面发送的值进行比较的第三方盒子。我遇到一个问题,用户为第三方盒子输入的网络掩码为 255.255.255.000,而盒子将其存储为 255.255.255.0。然而,下次盒子重新启动并被告知掩码包含 000 时,它断定这些值不同并更新其数据库并重新启动。并重新启动。并重新启动。
我的目的是通过将网络掩码以简化形式 255.255.255.0 存储在我自己的系统中来解决这个问题(另一个例子是将 010.001.002.005 存储为 10.1.2.5)。但我是 PHP 的新手。我尝试使用代码 $mask = long2ip(ip2long($mask))
将条目转换为标准化形式,但只返回 0.0.0.0。我需要做些什么来将 IP 转换为 long 和 back 吗?有没有更好的方法来简化这个?
ip2long
returns false 错误,它似乎没有检测到 000 为有效。由于 255.255.255.000
未被检测为有效 IP,它将 return 为假,因此 long2ip(false)
不会吐出有效 IP。
您甚至可以在接受 IP 地址之前检查 ip2long(input)
return 是否正确。进行适当的验证可以防止无效的 IP 破坏系统。尝试对所有可能的无效 IP 地址实施自动更正将比仅强制执行一个有效的 IP 地址要困难得多。
按照评论中@ka_lin 的建议,只需将其分解成多个部分,将其转换为一个 int,它将删除前导 0 并使用 implode 重建它...
$mask = implode(".", array_map("intval", explode(".", $mask)));
一个简单且开销较少的版本假定 IP 地址由 4 个部分组成...
list ($o1, $o2, $o3, $o4) = explode(".", $mask);
$mask = (int)$o1.".".(int)$o2.".".(int)$o3.".".(int)$o4;
这很难,因为 010.001.002.005 是一个有效的 IP 地址,但也可能令人困惑(有时以 0 开头的数字是八进制的)。
注意:ip2long()
有一个问题:它不接受有效的 IP 地址 127.1
(经典的表示法,但有效!)或 127.0.0.010
(RFC 表示无效,但大多数人将 010
读作八进制数)。
gethostbyname()
的备选方案。但是 gethostbyname()
也有问题:如果输入了无效的 ip(如 127.0.0.1234
),它会进行 DNS 查找和 returns 源,如果查找失败。
解决方案可以是:
long2ip(ip2long(gethostbyname($IP_ADDRESS)))
我个人的解决方案是以下功能:
function aton ( $addr )
{
$l = explode('.',$addr);
switch (count($l))
{
case 0: return FALSE;
case 1: return intval($l[0]) & 0xffffffff;
case 2: return ( intval($l[0]) << 24
| intval($l[1])
) & 0xffffffff;
case 3: return ( intval($l[0]) << 24
| intval($l[1]) << 16
| intval($l[2])
) & 0xffffffff;
default: return ( intval($l[0]) << 24
| intval($l[1]) << 16
| intval($l[2]) << 8
| intval($l[3])
) & 0xffffffff;
}
}
有了这个功能,您可以使用:
long2ip(aton($IP_ADDRESS))
顺便说一句,我从来没有遇到过像 255.255.255.0
.