如果 2 个 IPv6 地址相等,我如何签入 PHP?
How can I check in PHP if 2 IPv6-Adresses are equal?
我想检查 IP 是否在白名单中,但 IPv6 地址可以有不同的表示形式:
例如2001:0DB8:0:0:1::1
是2001:0db8:0000:0000:0001:0000:0000:0001
的缩写形式。
因此,字符串比较不起作用。我怎么知道两个地址相等?
使用inet_pton.
function is_ip_equal($ip1, $ip2) {
return inet_pton($ip1) == inet_pton($ip2);
}
(但是,这仅在 PHP 未使用 --disable-ipv6 option
编译时有效。您可以使用 if (!defined('AF_INET6')) echo "IPv6 support was disabled";
进行检查)。
inet_pton
不会去掉带括号的 IPv6 地址中的括号,这只对非常具体的用例很重要:inet_pton("[::1]")
returns FALSE。这是因为括号内的地址在技术上不是有效的 IPv6 地址(相反,括号内的地址 包含 一个 IPv6 地址),即使当 IPv6 在 URL 中时括号是必需的。
这里是 Ipv6-only 函数:
$bothBracketsArray = array('[', ']');
function are_ipv6_equal($a, $b) {
global $bothBracketsArray;
return inet_pton(str_replace($bothBracketsArray, '', $a)) === inet_pton(str_replace($bothBracketsArray, '', $b));
}
$bothBracketsArray
是全局的,因此 PHP 不必每次都分配一个新数组或对其模板进行浅表克隆(或任何 PHP现在正在做)。
我自己的目的还需要比较端口号和处理 IPv4,因为我正在监视 netstat 的输出以查看哪个进程 PID 在套接字的另一端。
$bothBracketsArray = array('[', ']');
function doIpsAndPortsEqual($a, $b) {
global $bothBracketsArray;
$lastPosA = strrpos($a, ":"); // port #
$lastPosB = strrpos($b, ":"); // port #
if (substr($a, $lastPosA+1) !== substr($b, $lastPosB+1)) return false;
$ipA = substr($a, 0, $lastPosA);
$ipB = substr($a, 0, $lastPosB);
if (strpos($ipA, ':') !== false) { // Ipv6
return inet_pton(str_replace($bothBracketsArray, '', $ipA)) === inet_pton(str_replace($bothBracketsArray, '', $ipB));
} else { // Ipv4
return $ipA === $ipB;
}
}
我想检查 IP 是否在白名单中,但 IPv6 地址可以有不同的表示形式:
例如2001:0DB8:0:0:1::1
是2001:0db8:0000:0000:0001:0000:0000:0001
的缩写形式。
因此,字符串比较不起作用。我怎么知道两个地址相等?
使用inet_pton.
function is_ip_equal($ip1, $ip2) {
return inet_pton($ip1) == inet_pton($ip2);
}
(但是,这仅在 PHP 未使用 --disable-ipv6 option
编译时有效。您可以使用 if (!defined('AF_INET6')) echo "IPv6 support was disabled";
进行检查)。
inet_pton
不会去掉带括号的 IPv6 地址中的括号,这只对非常具体的用例很重要:inet_pton("[::1]")
returns FALSE。这是因为括号内的地址在技术上不是有效的 IPv6 地址(相反,括号内的地址 包含 一个 IPv6 地址),即使当 IPv6 在 URL 中时括号是必需的。
这里是 Ipv6-only 函数:
$bothBracketsArray = array('[', ']');
function are_ipv6_equal($a, $b) {
global $bothBracketsArray;
return inet_pton(str_replace($bothBracketsArray, '', $a)) === inet_pton(str_replace($bothBracketsArray, '', $b));
}
$bothBracketsArray
是全局的,因此 PHP 不必每次都分配一个新数组或对其模板进行浅表克隆(或任何 PHP现在正在做)。
我自己的目的还需要比较端口号和处理 IPv4,因为我正在监视 netstat 的输出以查看哪个进程 PID 在套接字的另一端。
$bothBracketsArray = array('[', ']');
function doIpsAndPortsEqual($a, $b) {
global $bothBracketsArray;
$lastPosA = strrpos($a, ":"); // port #
$lastPosB = strrpos($b, ":"); // port #
if (substr($a, $lastPosA+1) !== substr($b, $lastPosB+1)) return false;
$ipA = substr($a, 0, $lastPosA);
$ipB = substr($a, 0, $lastPosB);
if (strpos($ipA, ':') !== false) { // Ipv6
return inet_pton(str_replace($bothBracketsArray, '', $ipA)) === inet_pton(str_replace($bothBracketsArray, '', $ipB));
} else { // Ipv4
return $ipA === $ipB;
}
}