PHP:将in_addr解包为int型的字符串表示形式


PHP: unpacking in_addr to a string representation of an int

inet_pton函数返回一个封装in_addr表示形式的IP地址,即::1变成' '。如何将这个16字节的值转换为整数?

Matty,似乎应该有一个大写的"a "在unpack()函数中使用,否则你将失去最后4位,如果它们是空的:

$unpacked = unpack('a16', $in_addr);

2001:0db8:11a3:09d7:1f34:8a2e: 07 a0:7600被转换为字符串(120)

$unpacked = unpack('A16', $in_addr);

2001:0db8:11a3:09d7:1f34:8a2e: 07 a0:7600被转换为字符串(128)

此解决方案也可用于相同的转换结果

如下代码所示:

$in_addr = inet_pton('21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A');
$unpacked = unpack('a16', $in_addr);
$unpacked = str_split($unpacked[1]);
$binary = '';
foreach ($unpacked as $char) {
    $binary .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
}
$gmp = gmp_init($binary, 2);
$str = gmp_strval($gmp);

你也可以用下面的代码反转它:

$gmp = gmp_init($str);
$binary = gmp_strval($gmp, 2);
$binary = str_pad($binary, 128, '0', STR_PAD_LEFT);
$binary_arr = str_split($binary, 8);
$packed = '';
foreach ($binary_arr as $char) {
    $packed .= chr(bindec($char));
}
$packed = pack('a16', $packed);
echo inet_ntop($packed);

您不能在PHP数字中精确地表示16字节(128位)整数——它们通常以双精度存储,在此之前会失去精度。下面是如何在不使用GMP的情况下将一个整数解压缩为四个32位整数:

$in_addr = inet_pton('2001:0db8:85a3:0000:0000:8a2e:0370:7334');
list($junk, $a, $b, $c, $d) = unpack("N4", $in_addr);
printf("%08x %08x %08x %08x", $a, $b, $c, $d);

还要注意inet_ntop函数,它将把inet_pton的输出转换回人类可读的格式。