将数字恢复为 IPv6 字符串表示
Revert number to IPv6 string representation
我正在使用 IP2Location 数据库查找 IPv6 地址的国家/地区代码。他们有一个 method 将 IPv6 地址转换为可用于查询其数据库的(大)数字。
$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);
在这种情况下,$ipv6long
将是 47875086426098177934326549022813196294。
现在我想知道是否可以将这样的数字还原为地址的 IPv6 字符串表示形式。如果是,怎么做?
回答我自己的问题:这会起作用:
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);
将显示 2404:6800:4001:805::1006。
inet_ntop()
可以格式化IPv6地址,但需要先转换为压缩字符串(16个字符的字符串,每个字符是数字的一个字节)。
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);
我正在使用 IP2Location 数据库查找 IPv6 地址的国家/地区代码。他们有一个 method 将 IPv6 地址转换为可用于查询其数据库的(大)数字。
$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);
在这种情况下,$ipv6long
将是 47875086426098177934326549022813196294。
现在我想知道是否可以将这样的数字还原为地址的 IPv6 字符串表示形式。如果是,怎么做?
回答我自己的问题:这会起作用:
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);
将显示 2404:6800:4001:805::1006。
inet_ntop()
可以格式化IPv6地址,但需要先转换为压缩字符串(16个字符的字符串,每个字符是数字的一个字节)。
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);