2

This is essentially a duplicate of this question: How to check an IP address is within a range of two IPs in PHP?

However the solution to the above question does not support ipv6. Is there a similar solution with ipv6 support?

4

1 回答 1

2

建议:

string inet_ntop ( string $in_addr )

此函数将 32 位 IPv4 或 128 位 IPv6 地址(如果 PHP 是在启用 IPv6 支持的情况下构建的)转换为地址族适当的字符串表示形式。

你还应该看到,

string inet_pton ( string $address )

inet_ntop() 示例

<?php
$packed = chr(127) . chr(0) . chr(0) . chr(1);
$expanded = inet_ntop($packed);

/* Outputs: 127.0.0.1 */
echo $expanded;

$packed = str_repeat(chr(0), 15) . chr(1);
$expanded = inet_ntop($packed);

/* Outputs: ::1 */
echo $expanded;
?>

范围比较

以下两个函数是在 PHP 5.1.0 中引入的,inet_ptoninet_pton. 它们的目的是将人类可读的 IP 地址转换为它们的打包in_addr表示。由于结果不是纯二进制,我们需要使用该unpack函数来应用位运算符。

这两个函数都支持 IPv6 和 IPv4。唯一的区别是您如何从结果中解压缩地址。使用 IPv6,您将使用 A16 解包内容,使用 IPv4,您将使用 A4 解包。

为了将前面的内容放在一个角度来看,这里有一个小示例输出以帮助澄清:

// Our Example IP's
$ip4= "10.22.99.129";
$ip6= "fe80:1:2:3:a:bad:1dea:dad";


// ip2long examples
var_dump( ip2long($ip4) ); // int(169239425)
var_dump( ip2long($ip6) ); // bool(false)


// inet_pton examples
var_dump( inet_pton( $ip4 ) ); // string(4)
var_dump( inet_pton( $ip6 ) ); // string(16)

我们在上面演示了 inet_* 系列支持 IPv6 和 v4。我们的下一步是将打包的结果转换为未打包的变量。

// Unpacking and Packing
$_u4 = current( unpack( "A4", inet_pton( $ip4 ) ) );
var_dump( inet_ntop( pack( "A4", $_u4 ) ) ); // string(12) "10.22.99.129"


$_u6 = current( unpack( "A16", inet_pton( $ip6 ) ) );
var_dump( inet_ntop( pack( "A16", $_u6 ) ) ); //string(25) "fe80:1:2:3:a:bad:1dea:dad"

注意:当前函数返回数组的第一个索引。相当于说 $array[0]。

解包打包后,我们可以看到我们得到了和输入一样的结果。这是一个简单的概念证明,以确保我们不会丢失任何数据。

最后使用,

if ($ip <= $high_ip && $low_ip <= $ip) {
  echo "in range";
}

参考:php.net

于 2015-12-28T20:29:25.293 回答