I have a bunch of IP-addresses stored in an array, e.g.:
my @ip = qw(10.11.1.1 10.100.1.1 ...);
How can I sort the addresses in the ascending order? I've tried a simple sort
but it failed, of course.
IPv4 addresses are just 32-bit numbers.
use Socket qw( inet_aton );
my @sorted =
map substr($_, 4),
sort
map inet_aton($_) . $_,
@ips;
or
my @sorted =
map substr($_, 4),
sort
map pack('C4a*', split(/\./), $_),
@ips;
The first one also accepts domain names.
I'm not fond of any solution that assumes more that it needs. I've been burned on this sort of thing by compact notation before, and I imagine this problem gets tougher when IPv6 becomes more common. I'd just let Net::IP figure it out:
use 5.010;
use Net::IP;
my @ip = qw(
192.168.1.10
172.16.5.5
256.0.0.1
192.168.1/24
127.1
127.0.1
fd00:6587:52d7:f8f7:5a55:caff:fef5:af31
fd24:cd9b:f001:884c:5a55:caff:fef5:af31
);
my @sorted =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, eval { Net::IP->new( $_ )->intip } ] }
@ip;
say join "\n", @sorted;
This handles the compact and range notations just fine and the eval
catches the bad IP addresses. I don't have to treat IPv4 and IPv6 separately:
256.0.0.1
127.0.1
127.1
172.16.5.5
192.168.1/24
192.168.1.10
fd00:6587:52d7:f8f7:5a55:caff:fef5:af31
fd24:cd9b:f001:884c:5a55:caff:fef5:af31
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With