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:

  1. IPv6 support
  2. 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));
}

Tags:

Php