public static function cidrMatch($ip, $range)
{
if (strpos($range, '/') === false) {
$bits = null;
$subnet = $range;
} else {
list($subnet, $bits) = explode('/', $range);
}
$ip = inet_pton($ip);
$subnet = inet_pton($subnet);
if ($ip === false || $subnet === false) {
return false;
}
if (strlen($ip) > strlen($subnet)) {
$subnet = str_pad($subnet, strlen($ip), chr(0), STR_PAD_LEFT);
} elseif (strlen($subnet) > strlen($ip)) {
$ip = str_pad($ip, strlen($subnet), chr(0), STR_PAD_LEFT);
}
if ($bits === null) {
return $ip === $subnet;
} else {
for ($i = 0; $i < strlen($ip); $i++) {
$mask = 0;
if ($bits > 0) {
$mask = $bits >= 8 ? 255 : 256 - (1 << 8 - $bits);
$bits -= 8;
}
if ((ord($ip[$i]) & $mask) !== (ord($subnet[$i]) & $mask)) {
return false;
}
}
}
return true;
}