我见过的关于在PHP中验证私有IP的大多数问题都与验证特定IP地址是否为私有IP,或者IP是否存在于特定范围内有关。
但是,我希望能够在PHP中确定是否以IP格式给出的IP范围。 “X.X.X.X - Y.Y.Y.Y”是一个专属私人系列。就这么清楚,我想知道整个范围是否是私有的。例子:
10.0.0.1 - 10.0.0.14
将返回true,因为此范围内的所有IP都是内部的。
10.0.0.1 - 127.0.0.16
将返回false,因为并非所有范围内的IP都是内部/私有的,即使起点和终点是。
我最初的想法只是验证开始和结束IP,如果它们是内部的,那么一切都很好。但是,正如我上面所说,如果我有一个类似$range = '10.0.0.1 - 127.0.0.16'
的范围,而起始和结束IP地址都被认为是私有IP地址,它跨越非内部的IP地址,因此它不是一个专门的内部IP地址范围。
我或许可以在该范围内生成每个IP地址,并对每个IP地址进行验证,但这看起来非常低效。
是否有更简单,更有效的方法?
编辑:只是为了让那些标记为重复的人更加明确:我不是要验证单个给定的IP并查看它是否是私有的。我想检查格式为$range = '10.0.0.1 - 127.0.0.16'
的给定范围内的每个可能的IP是否为私有。做这样的事情太慢而且效率低下(假设我已经爆炸了字符串以获取起始和结束IP地址):
<?php
function checkRange($start, $end)
{
$start = ip2long($start);
$end = ip2long($end);
for ($i = $start; $i <= $end; $i++) {
$ip = long2ip($i);
if (!filter_var(
$ip,
FILTER_VALIDATE_IP,
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_IPV4
)) {
continue;
}
return false;
}
return true;
}
答案 0 :(得分:3)
IP空间中的所有私有范围均以公开范围分隔(私有p
,公共_
公开):
__ppp___pppp___ppp___
如果您希望用户定义的范围完全私有,则需要将其完全包含在其中一个私有范围内(u
用于用户定义的所有私有范围=命中,x
表示错误的范围,失败):
__ppp___pppp___ppp___
uu
u
xxxxxxx
uu
u
因此,我们需要检查两个输入值($start
和$end
)是否不仅是私有的,还是在同一个私有范围内。
function checkRange($start, $end)
{
$start = ip2long($start);
$end = ip2long($end);
if (!$start || !$end)
throw new Exception('Invalid input.');
if ($start > $end)
throw new Exception('Invalid range.'); // Alternative: switch $start and $end
$range1_start = ip2long('10.0.0.0');
$range1_end = ip2long('10.255.255.255');
$range2_start = ip2long('172.16.0.0');
$range2_end = ip2long('172.31.255.255');
$range3_start = ip2long('192.168.0.0');
$range3_end = ip2long('192.168.255.255');
return ($start >= $range1_start && $start <= $range1_end &&
$end >= $range1_start && $end <= $range1_end) ||
($start >= $range2_start && $start <= $range2_end &&
$end >= $range2_start && $end <= $range2_end) ||
($start >= $range3_start && $start <= $range3_end &&
$end >= $range3_start && $end <= $range3_end);
}
答案 1 :(得分:0)
IP地址是32位数。它可以表示为由句点分隔的四个小数,每个小数是基数10中32位数的8位。 PHP的内置http://wiki.fasterxml.com/JacksonJsonViews从IPv4 字符串表示法转换为标准的32位整数。
考虑到这一点(IPv4字符串表示法字符串只是32位整数),您可以轻松地提出一种算法,检查整数是否在某个范围内,或者范围是否在另一个范围内。
<?php
function check($start, $end) {
$r10Start = ip2long('10.0.0.0');
$r10End = ip2long('10.255.255.255');
$r127Start = ip2long('127.0.0.0');
$r127End = ip2long('127.255.255.255');
if (
($start >= $r10Start && $end <= $r10End)
|| ($start >= $r127Start && $end <= $r127End)
) {
return true;
}
return false;
}
var_dump(check(ip2long('10.0.0.1'), ip2long('10.0.0.14')));
var_dump(check(ip2long('10.0.0.1'), ip2long('127.0.0.16')));