开发者

PHP: unpacking in_addr to a string representation of an int

The inet_pton function returns an IP address in its packed in_addr representation, i.e. ::1 becomes ``. How can I convert this 16-byte value to an integer? (Well,开发者_JS百科 the string representation of an integer.)


Matty, seems there should be a capital "A" used in unpack() functions, otherwise you will lose last 4 bits if they are nulls:

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

2001:0db8:11a3:09d7:1f34:8a2e:07a0:7600 is converted to string(120)

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

2001:0db8:11a3:09d7:1f34:8a2e:07a0:7600 is converted to string(128)

Also this solution can be used for same conversion results.


The following code does it:

$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);

You can also reverse it with the following code:

$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);


You can't represent a 16-byte (128-bit) integer precisely in a PHP number -- they're typically stored as doubles, which lose precision before then. Here's how you can unpack one into four 32-bit integers without using GMP, though:

$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);

Also note the inet_ntop function, which will turn the output of inet_pton back into a human-readable format.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜