I have a PHP application which needs to store IPv6 addresses in sorted order. I have written a comparison operation for IPv6 addresses which uses "inet" and "gmp" library functions, but I'm looking for a more efficient way to do this - ideally by operating directly on the 16 byte packed string representation of the IPv6 address. Is there a convenient way to do this (without compiling a custom PHP extension)?
EDIT: I'm interested in both time and space efficiency, here, which is why I'm attracted by the idea of using a packed string representation. And although I'm aware that there are fancy trie-based representations of IPv6 sets used by routers to optimize certain search operations, I'm not asking for references to any C libraries or research papers in this question. I'm asking specifically about sorting in PHP, which is quite different from sorting in C, Perl, or Python. The number of address to be managed is < 100 million, but more than 1 million.
As pointed out by Michael Hampton in the comments, sort() and ksort() ought to work just fine on packed strings. Here's a script to demonstrate:
<?php
if (defined('AF_INET6')) {
echo "PHP was compiled without --disable-ipv6 option";
} else {
echo "PHP was compiled with --disable-ipv6 option";
}
$a = array(
inet_pton('::1'),
inet_pton('1::'),
inet_pton('::a'),
inet_pton('a::'),
inet_pton('20::'),
inet_pton('::20'),
inet_pton('9::'),
inet_pton('::9')
);
print "\nbefore sort:\n";
foreach ($a as $r) { print inet_ntop($r) . "\n"; flush(); }
sort($a);
print "\nafter sort:\n";
foreach ($a as $r) { print inet_ntop($r) . "\n"; flush(); }
When I run this in my development environment, I get the following output, which is correct:
PHP was compiled without --disable-ipv6 option
before sort:
::1
1::
::a
a::
20::
::20
9::
::9
after sort:
::1
::9
::a
::20
1::
9::
a::
20::
So the Good News appears to be that inet_pton(), inet_ntop(), sort(), and ksort() will "just work" the way I want them to.
This makes me happy. And surprised, in a Good Way, by PHP!
EDIT: There appears to be a bug in inet_pton which complicates the use of Michael Hampton's "obvious" approach. Fortunately, there are ways to work around it.