Поскольку вы не можете преобразовать адреса IPv6 в целое число, вы должны использовать биты, например:
$ip='21DA:00D3:0000:2F3B:02AC:00FF:FE28:9C5A';
$cidrnet='21DA:00D3:0000:2F3B::/64';
// converts inet_pton output to string with bits
function inet_to_bits($inet)
{
$unpacked = unpack('A16', $inet);
$unpacked = str_split($unpacked[1]);
$binaryip = '';
foreach ($unpacked as $char) {
$binaryip .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
}
return $binaryip;
}
$ip = inet_pton($ip);
$binaryip=inet_to_bits($ip);
list($net,$maskbits)=explode('/',$cidrnet);
$net=inet_pton($net);
$binarynet=inet_to_bits($net);
$ip_net_bits=substr($binaryip,0,$maskbits);
$net_bits =substr($binarynet,0,$maskbits);
if($ip_net_bits!==$net_bits) echo 'Not in subnet';
else echo 'In subnet';
Кроме того, если вы используете некоторую базу данных для хранения IP-адресов, она может уже иметь все функции для их сравнения,Например, Postgres имеет тип inet и может определять, содержится ли IP в подсети, например:
SELECT
'21DA:00D3:0000:2F3B:02AC:00FF:FE28:9C5A'::inet <<
'21DA:00D3:0000:2F3B::/64'::inet;
9.11.Функции и операторы сетевых адресов в PostgreSQL