检查IP地址是否为私有

Rut*_*uth 17 php ip private

我想检查IP地址是否在专用网络中.它不起作用.

我的代码:

<?php
$ip = $_SERVER['REMOTE_ADDR'];

function _isPrivate($ip) 
{
    $i = explode('.', $ip);

    if ($i[0] == 10) {
        return true;
    } else if ($i[0] == 172 && $i[1] > 15 && $i[1] < 32) {
        return true;
    } else if ($i[0] == 192 && $i[1] == 168) {
        return true;
    }
    return false;
}
?>
Run Code Online (Sandbox Code Playgroud)

另一个:

<?php
$ip = $_SERVER['REMOTE_ADDR'];

function _isPrivate($ip) 
{
    $ip = ip2long($ip);
    $net_a = ip2long('10.255.255.255') >> 24; 
    $net_b = ip2long('172.31.255.255') >> 20; 
    $net_c = ip2long('192.168.255.255') >> 16; 

    return $ip >> 24 === $net_a || $ip >> 20 === $net_b || $ip >> 16 === $net_c; 
}
?>
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激,谢谢!

Dmi*_*tin 70

我认为这应该可以解决问题.

如果IP地址是私有IP地址,则使用以下验证规则的filter_var将返回false.

$user_ip = '127.0.0.1';
filter_var(
    $user_ip, 
    FILTER_VALIDATE_IP, 
    FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE |  FILTER_FLAG_NO_RES_RANGE
)
Run Code Online (Sandbox Code Playgroud)

检查上面的链接以获取php文档

  • 您可能希望添加指向`filter_var()`的链接以及PHP手册的验证过滤器页面.即http://php.net/manual/en/function.filter-var.php和http://php.net/manual/en/filter.filters.validate.php (4认同)
  • 如果您想同时处理 IPv4 和 IPv6,删除 `FILTER_FLAG_IPV4` 也有效 (4认同)
  • 您还可以添加"FILTER_FLAG_IPV6"以允许私有IPv6地址. (2认同)
  • 如果你想要一个逻辑结果,检查是否 ($user_ip == filter_var($user_ip ...)) - 添加这个,因为它浪费了我一点时间记住 filter_var 是如何工作的:) (2认同)

Mar*_*son 23

function ip_is_private ($ip) {
    $pri_addrs = array (
                      '10.0.0.0|10.255.255.255', // single class A network
                      '172.16.0.0|172.31.255.255', // 16 contiguous class B network
                      '192.168.0.0|192.168.255.255', // 256 contiguous class C network
                      '169.254.0.0|169.254.255.255', // Link-local address also refered to as Automatic Private IP Addressing
                      '127.0.0.0|127.255.255.255' // localhost
                     );

    $long_ip = ip2long ($ip);
    if ($long_ip != -1) {

        foreach ($pri_addrs AS $pri_addr) {
            list ($start, $end) = explode('|', $pri_addr);

             // IF IS PRIVATE
             if ($long_ip >= ip2long ($start) && $long_ip <= ip2long ($end)) {
                 return true;
             }
        }
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

请参阅http://mebsd.com/coding-snipits/check-private-ip-function-php.html

您可能还想查看有关私人地址空间的信息

  • 我猜,但这段代码很糟糕.如果你打算用其他人的代码回答(虽然有信用),你至少不能格式化它以便它可读吗?此外,这包括环回和自动配置范围,这可能是不希望的. (4认同)

Dea*_*ouL 5

好的,这是 7 年前的帖子。但我想我可以分享我的解决方案,这样也许某个地方的某个人可能会发现它有帮助。

我的解决方案基于内置的 PHP filter_var() 函数。这意味着我不必每次需要验证给定值时都预先定义所有私有范围或保留范围。或者循环遍历范围。相反,我让 PHP 为我担心。

class IP
{
    static public function is_ip($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_ipv4($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_ipv6($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV6
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_public_ip($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_public_ipv4($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_public_ipv6($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_private_ip($ip=NULL) : bool
    {
        return self::is_ip($ip) && !self::is_public_ip($ip);
    }

    static public function is_private_ipv4($ip=NULL) : bool
    {
        return self::is_ipv4($ip) && !self::is_public_ipv4($ip);
    }

    static public function is_private_ipv6($ip=NULL) : bool
    {
        return self::is_ipv6($ip) && !self::is_public_ipv6($ip);
    }
}
Run Code Online (Sandbox Code Playgroud)

它允许您验证给定的值,无论它是否是 IP。或者更具体一点。您可以验证以下类型:

  • 知识产权
  • IPv4
  • IPv6
  • 公网IP
  • 公共 IPv4
  • 公共 IPv6
  • 私有IP
  • 私有 IPv4
  • 私有 IPv6

让我们测试一下:

$arr = array(
    '127.0.0.0', '127.0.0.1', '127.1.2.3', '127.1.2.255',

    '192.168.0.0', '192.168.0.1', '192.168.2.3', '192.168.2.255',

    '172.16.0.0', '172.16.0.1', '172.16.2.3', '172.16.2.255',
    '172.19.0.0', '172.19.0.1', '172.19.2.3', '172.19.2.255',

    '10.0.0.0', '10.0.0.1', '10.0.2.3', '10.0.2.255',
    '10.5.0.0', '10.5.0.1', '10.5.2.3', '10.5.2.255',

    '8.8.8.8', '8.8.4.4', '255.255.255',

    '182.168.1.300', '256.1.2.3', '0.500.0.0',
    'I am not an IP', NULL, '185.128.72.151'
);

foreach ($arr as $item) {
    echo "$item --> " . (IP::is_private_ip($item) === TRUE ? 'is private' : 'is NOT private or NOT an IP') . PHP_EOL;
}
Run Code Online (Sandbox Code Playgroud)