0

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, the string representation of an integer.)

Matty
  • 33,203
  • 13
  • 65
  • 93

3 Answers3

2

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.

Community
  • 1
  • 1
Snifff
  • 1,784
  • 2
  • 16
  • 28
1

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);
Matty
  • 33,203
  • 13
  • 65
  • 93
0

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.

  • I had no idea about the `pack` and `unpack` functions. I actually do need a GMP resource as I need to do some bitwise operations on the resulting number. This answer has helped me come up with a more elegant solution - I've amended my answer. Thanks! – Matty Aug 03 '11 at 21:57