Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I sort a list of IP-addresses in Perl?

Tags:

sorting

perl

ipv4

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.

like image 559
planetp Avatar asked Aug 02 '11 19:08

planetp


2 Answers

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.

like image 147
ikegami Avatar answered Nov 14 '22 23:11

ikegami


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
like image 35
brian d foy Avatar answered Nov 15 '22 00:11

brian d foy