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.
精彩评论