Php convert ipv6 to number
Use:
$ip = 'fe80:0:0:0:202:b3ff:fe1e:8329';
$dec = ip2long_v6($ip);
$ip2 = long2ip_v6($dec);
// $ip = fe80:0:0:0:202:b3ff:fe1e:8329
// $dec = 338288524927261089654163772891438416681
// $ip2 = fe80::202:b3ff:fe1e:8329
Functions:
With enabled GMP or BCMATH extension.
function ip2long_v6($ip) {
$ip_n = inet_pton($ip);
$bin = '';
for ($bit = strlen($ip_n) - 1; $bit >= 0; $bit--) {
$bin = sprintf('%08b', ord($ip_n[$bit])) . $bin;
}
if (function_exists('gmp_init')) {
return gmp_strval(gmp_init($bin, 2), 10);
} elseif (function_exists('bcadd')) {
$dec = '0';
for ($i = 0; $i < strlen($bin); $i++) {
$dec = bcmul($dec, '2', 0);
$dec = bcadd($dec, $bin[$i], 0);
}
return $dec;
} else {
trigger_error('GMP or BCMATH extension not installed!', E_USER_ERROR);
}
}
function long2ip_v6($dec) {
if (function_exists('gmp_init')) {
$bin = gmp_strval(gmp_init($dec, 10), 2);
} elseif (function_exists('bcadd')) {
$bin = '';
do {
$bin = bcmod($dec, '2') . $bin;
$dec = bcdiv($dec, '2', 0);
} while (bccomp($dec, '0'));
} else {
trigger_error('GMP or BCMATH extension not installed!', E_USER_ERROR);
}
$bin = str_pad($bin, 128, '0', STR_PAD_LEFT);
$ip = array();
for ($bit = 0; $bit <= 7; $bit++) {
$bin_part = substr($bin, $bit * 16, 16);
$ip[] = dechex(bindec($bin_part));
}
$ip = implode(':', $ip);
return inet_ntop(inet_pton($ip));
}
demo
Note that all answers will result in incorrect results for big IP addresses or are going through a highly complicated process to receive the actual numbers. Retrieving the actual integer value from an IPv6 address requires two things:
- IPv6 support
- GMP extension (
--with-gmp
)
With both prerequisites in place conversion is as simple as:
$ip = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff';
$int = gmp_import(inet_pton($ip));
echo $int; // 340282366920938463463374607431768211455
The binary numeric packed in_addr
representation that is returned by inet_pton
is already an integer and can directly be imported to GMP, as illustrated above. There is no need for special conversions or anything.
Note that the other way around is equally simple:
$int = '340282366920938463463374607431768211455';
$ip = inet_ntop(str_pad(gmp_export($int), 16, "\0", STR_PAD_LEFT));
echo $ip; // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
Hence building the two desired functions is as simple as:
function ipv6_to_integer($ip) {
return (string) gmp_import(inet_pton($ip));
}
function ipv6_from_integer($integer) {
return inet_ntop(str_pad(gmp_export($integer), 16, "\0", STR_PAD_LEFT));
}