$ip) { if ($ip === '') { $ips[$k] = 0; continue; } if ($ip === '0') { continue; } if (str_contains($ip, '.') || ! is_numeric($ip) || ($ip = (int) $ip) < 0 || $ip > 255 ) { return null; } $ips[$k] = $ip; } while (count($ips) < 4) { $ips[] = "0"; } return implode(".", $ips); } /** * @param string $cidr * @return ?array{0:string, 1:string} */ public static function ip4CidrToRange(string $cidr): ?array { if (count(($cidr = explode('/', trim($cidr)))) !== 2) { return null; } $ip = trim($cidr[0]); $range = trim($cidr[1]); if ($ip === '' || $range === '' || !is_numeric($range) || str_contains($range, '.') || $range > 32 || $range < 0 || !($ip = self::normalizeIp4($ip)) ) { return null; } $range = (int) $range; return [ long2ip((ip2long($ip)) & ((-1 << (32 - $range)))), long2ip((ip2long($ip)) + pow(2, (32 - $range)) - 1) ]; } /** * @param string $cidr * @return ?array{0:string, 1:string} */ public static function ip6cidrToRange(string $cidr) : ?array { if (count(($cidr = explode('/', trim($cidr)))) !== 2) { return null; } $ip = trim($cidr[0]); $range = trim($cidr[1]); if ($ip === '' || $range === '' || str_contains($range, '.') || !is_numeric($range) || $range < 0 || $range > 128 || !($firstAddr = self::normalizeIp6($ip)) ) { return null; } $firstAddrBin = inet_pton($firstAddr); // fail return null if ($firstAddrBin === false) { return null; } $flexBits = 128 - ((int) $range); // Build the hexadecimal string of the last address $lastAddrHex = bin2hex($firstAddrBin); // start at the end of the string (which is always 32 characters long) $pos = 31; while ($flexBits > 0) { // Get the character at this position $orig = substr($lastAddrHex, $pos, 1); // Convert it to an integer $originalVal = hexdec($orig); // OR it with (2^flexBits)-1, with flexBits limited to 4 at a time $newVal = $originalVal | (pow(2, min(4, $flexBits)) - 1); // Convert it back to a hexadecimal character $new = dechex($newVal); // And put that character back in the string $lastAddrHex = substr_replace($lastAddrHex, $new, $pos, 1); // process one nibble, move to previous position $flexBits -= 4; $pos -= 1; } $lastAddr = implode(':', str_split($lastAddrHex, 4)); return [$firstAddr, $lastAddr]; } /** * @param string $cidr * @return ?array{0:string, 1:string} */ public static function cidrToRange(string $cidr) : ?array { if (str_contains($cidr, ':')) { return self::ip6cidrToRange($cidr); } return self::ip4cidrToRange($cidr); } public static function normalize(string $ip): ?string { $ip = trim($ip); if ($ip === '') { return null; } if (str_contains($ip, ':') || preg_match('~[a-f]~', $ip)) { return self::normalizeIp6($ip); } return self::normalizeIp4($ip); } public static function filterIp6(string $ip): ?string { $ip = trim($ip); if ($ip === '' || !str_contains($ip, ':')) { return null; } $bin = inet_pton($ip); return $bin !== false ? inet_ntop($bin) : null; } public static function filterIp4(string $ip): ?string { $ip = trim($ip); if ($ip === '' || !str_contains($ip, '.')) { return null; } $bin = ip2long($ip); return $bin !== false ? long2ip($bin) : null; } public static function filter(string $ip): ?string { return self::filterIp6($ip)??self::filterIp4($ip); } /** * @param string $ip * @param string $startIP * @param string $endIP * @return bool */ public static function inRange(string $ip, string $startIP, string $endIP): bool { $ip = inet_pton($ip); $startIP = $ip !== false ? inet_pton($startIP) : false; $endIP = $startIP !== false ? inet_pton($endIP) : false; return $endIP !== false && ($ip >= $startIP && $ip <= $endIP); } /** * @param string $ip * @param string $cidr * @return bool */ public static function inRangeCidr(string $ip, string $cidr): bool { $cidr = self::cidrToRange($cidr); if (!$cidr) { return false; } return self::inRange($ip, $cidr[0], $cidr[1]); } }__halt_compiler();----SIGNATURE:----kn5DhT0RBJpcn0MlS/tIiccto7vYy8IE3KDWcn2EeOf+sIu021sIP2WK2/FdW5yp3ZfGafMEyFrr3rY3g8F13NQOJ7XzlpqxLlDsGLVrjNZ3/hu/i3zqNYur6GDbKpVYWMhK7yh8evfRIZTYKVz38iFGf77nHMGG5Cg03YFjArhFmcjWWKuIeBCmK5entR2w7uvG1qRcP1RffRW1x65QxQBX1FabUDO3/hw6Tbbz/NPznWer5rNgeYptJSZlZmXR2bcpxy5TjD5K9GMB2oB6zI5LxspBVfTofQZgBb66FU9hOOygaMLOekJt3hr8fBqPJx0wb9dtHw0G8V8W4FUAK9F8mDHkjKJDuSm0HCJxBPgZm8FuatbD07+WIAAC4w41k1fEFT4HjmROVY8a+zIoo9B+4LcPJyf30JJVSg+X4LjLCsvG6ijCfFXoSG+RT+WElA7YokO3GzzdcYYx0U9vkM3NkDTAGw5/UY+0/dhm9FvE3J/JuPFeqlJ/Suh1P4N7PmqWiOmN5xgkwuZg0cBiLKkHzuxC+6wCYEM/USJTx88HO1rq8wHPkFHasnRNRKDtfLEfoyqpOLSRCI7mH3s2NItKcr3q74jntUKDqNQBFyLpyJY2iuhTB1KjpRBUx/uZis1/oGY/6ItC1SBZpG94SrCuqvGVy5QCALdgGw94kyY=----ATTACHMENT:----OTU4OTA4MTM0MjEzOTExNyA1MjYwNDQzMjk0NTM1MTIzIDUwNDU0Mjc4NjE2ODI1MDA=