分类
碎碎念

PHP 判断 IP 是否在 CIDR 子网内

function cidr_match($ip, $range)
{
    list ($subnet, $bits) = explode('/', $range);
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
        if (!filter_var($subnet, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            return false;
        }
        $ip = inet_pton($ip);
        $subnet = inet_pton($subnet);
        for ($i = 0; $bits > 0 && $i < 16; $i++) {
            $v = substr($ip, $i, 1);
            $s = substr($subnet, $i, 1);
            if ($bits < 8) {
                $v = substr(str_pad(decbin(ord($v)), 8, '0', STR_PAD_LEFT), 0, $bits);
                $s = substr(str_pad(decbin(ord($s)), 8, '0', STR_PAD_LEFT), 0, $bits);
            }
            if ($v !== $s) {
                return false;
            }
            $bits -= 8;
        }
        return true;
    } else {
        if (!filter_var($subnet, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            return false;
        }
        $ip = ip2long($ip);
        $subnet = ip2long($subnet);
        $mask = -1 << (32 - $bits);
        $subnet &= $mask;
        return ($ip & $mask) == $subnet;
    }
}

支持 IPv4 和 IPv6 子网掩码判断,IPv6 代码参考自 Matching IPv6 address to a CIDR subnet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据