Revert number to IPv6 string representation

孤街浪徒 提交于 2019-12-11 10:19:00

问题


I'm using the IP2Location database to find country codes for IPv6 addresses. They have a method to convert an IPv6 address to a (large) number which can be used to query their database.

$ipv6 = '2404:6800:4001:805::1006';
$int = inet_pton($ipv6);
$bits = 15;

$ipv6long = 0;

while($bits >= 0){
    $bin = sprintf("%08b", (ord($int[$bits])));

    if($ipv6long){
        $ipv6long = $bin . $ipv6long;
    }
    else{
        $ipv6long = $bin;
    }
    $bits--;
}
$ipv6long = gmp_strval(gmp_init($ipv6long, 2), 10);

In this case, $ipv6long would be 47875086426098177934326549022813196294.

Now Im wondering whether such a number can be reverted to the IPv6 string representation of the address. And if so, how?


回答1:


inet_ntop() can format IPv6 addresses, but you need to convert to a packed string first (a 16 character string where each character is one byte of the number).

function ipv6number2string($number) {
    // convert to hex
    $hex = gmp_strval(gmp_init($number, 10), 16);
    // pad to 32 chars
    $hex = str_pad($hex, 32, '0', STR_PAD_LEFT);
    // convert to a binary string
    $packed = hex2bin($hex);
    // convert to IPv6 string
    return inet_ntop($packed);
}

echo ipv6number2string(47875086426098177934326549022813196294);



回答2:


To answer my own question: this will work:

function ipv6number2string($number) {
    // thanks to joost @ http://php.net/manual/en/function.dechex.php
    $hexvalues = array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
    $hexval = '';
    while($number != '0') {
        $hexval = $hexvalues[bcmod($number,'16')].$hexval;
        $number = bcdiv($number,'16',0);
    }

    // now format it with colons
    $str = '';
    preg_replace_callback('/([a-f0-9]{4})/', function($m) use (&$str) {
        if (empty($str)) {
            $str = is_numeric($m[0]) ? intval($m[0]) : $m[0];
        } else {
            $str .= ':' . (is_numeric($m[0]) ? intval($m[0]) : $m[0]);
        }
    }, $hexval);
    return preg_replace(array('/:0/', '/:{3,}/'), '::', $str);
}

echo ipv6number2string(47875086426098177934326549022813196294);

Will show 2404:6800:4001:805::1006.



来源:https://stackoverflow.com/questions/35204197/revert-number-to-ipv6-string-representation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!