我一直在尝试在 PHP 中实现一个使用 CIDR 表示法验证 IPv6 地址的函数。我在网上找到了一个适用于 IPv4 地址的函数,但是当我尝试将其修改为适用于 IPv6 时,它似乎没有按预期工作。
这是我正在使用的功能:
function valid_network($network) {
list($nw, $cidr) = explode('/', $network);
if (!filter_var($nw, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
return false;
}
$binary_address = inet_pton($nw);
$prefix_binary = str_pad('', (int)$cidr, '1') . str_pad('', 128 - (int)$cidr, '0');
$binary_network = inet_pton(inet_ntop($binary_address & $prefix_binary));
return $binary_address === $binary_network;
}
测试用例:
print_r( valid_network("2001:0db8:85a3:0000:0000:8a2e:0370:7334/64") ? "Valid\n" : "Invalid\n" ); // true
print_r( valid_network("2001:0db8:85a3:0000:0000:8a2e:0370:7334/48") ? "Valid\n" : "Invalid\n" ); // true
print_r( valid_network("2001:0db8:85a3:0000:0000:8a2e:0370:7334/127") ? "Valid\n" : "Invalid\n" ); // true
print_r( valid_network("2001:0db8:85a3:0000:0000:8a2e:0370:7334/128") ? "Valid\n" : "Invalid\n" ); // true (a /128 will always be true)
print_r( valid_network("2001:0db8:85a3:0000:0000:8a2e:0370:7334/64") ? "Valid\n" : "Invalid\n" ); // true
print_r( valid_network("2001:0db8:85a3:0000:0000:8a2e:0370:7334/63") ? "Valid\n" : "Invalid\n" ); // false
print_r( valid_network("2001:0db8:85a3:0000:0000:8a2e:0370:7334") ? "Valid\n" : "Invalid\n" ); // false (no CIDR notation)