CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Regular Expressions:
sorting IPs

 



monocle
User

Apr 5, 2001, 1:34 PM

Post #1 of 4 (1737 views)
sorting IPs Can't Post

OK... call me crazy but I want to sort a list of IPs

Currently I am using this:
@SORTED_IPS = sort keys %{ { map {$_ => 1} @IPS} };
This is how I sorted everything in the past and that works great...

except for IPs, it produces a list like this:
152.2.115.xxx
172.182.241.xxx
194.236.144.xxx
212.50.177.xxx
217.1.4.xxx
24.157.134.xxx
24.160.105.xxx
62.224.4.xxx
62.252.224.xxx
65.24.74.xxx
66.20.144.xxx

I don't like this. I want IPs with 1 or 2 digits in a set to appear before IPs with 3 digits in that same set like this:
24.157.134.xxx
24.160.105.xxx
62.224.4.xxx
62.252.224.xxx
65.24.74.xxx
66.20.144.xxx
152.2.115.xxx
172.182.241.xxx
194.236.144.xxx
212.50.177.xxx
217.1.4.xxx

Not sure if I am making any sense but I can't think of a better way to describe it. Imagine if each set within an IP were zero filled to 3 digits, the sort would come out the way I want it.. I don't really know anything about IPs so perhaps my wording is improper.

Any ideas?

Thanks



Jasmine
Administrator

Apr 5, 2001, 8:28 PM

Post #2 of 4 (1732 views)
Re: sorting IPs [In reply to] Can't Post

There's really no need for map here:


Code
@SORTED_IPS = sort { $a <=> $b } @ips; 

print join "\n", @SORTED_IPS;

The above prints:


Code
24.157.134.xxx 
24.160.105.xxx
62.224.4.xxx
62.252.224.xxx
65.24.74.xxx
66.20.144.xxx
152.2.115.xxx
172.182.241
194.236.144.xxx
212.50.177.xxx
217.1.4.xxx

The downside to this is that you'll get a lot of warnings that "24.157.134.xxx isn't numeric". You can avoid this by turning off warnings:


Code
no warnings; 
@SORTED_IPS = sort { $a <=> $b } @ips;
use warnings;

print join "\n", @SORTED_IPS;

Hope this helps!



japhy
Enthusiast / Moderator

Apr 6, 2001, 7:46 AM

Post #3 of 4 (1729 views)
Re: sorting IPs [In reply to] Can't Post

The fastest way to sort IP addresses is radix sort (look it up in your neighborhood friendly algorithm book).

Here's a Perl implementation:


Code
use Socket qw( inet_aton inet_ntoa ); 

sub IP_radix_sort {
for (my $i = 3; $i >= 0; $i--) {
my @table;
for (@_) {
push @{ $table[unpack "\@$i C", $_] }, $_;
}
@_ = map @$_, @table;
}
return @_;
}

sub IPsort {
map inet_ntoa($_),
IP_radix_sort
map inet_aton($_),
@_;
}

You call the function @sorted = IPsort @unsorted.

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author

(This post was edited by japhy on Apr 23, 2001, 7:16 AM)


monocle
User

Apr 6, 2001, 9:47 AM

Post #4 of 4 (1727 views)
Re: sorting IPs [In reply to] Can't Post

Thanks Jasmine

that worked. For some reason I don't get warnings about the IP not being numeric. and when I used the "no warnings" it breaks. I think my host is not using warnings. I get a "can't find warnings.pm" error in my logs... anyway all is good.

However, I forgot to mention that the map was there to strip out the duplicates. So now first I strip the duplicates using my original sort/map and then I sort them using your sort. Is there a way to combine these two steps back into one step?

PS. Glad to see you resolved the Netscape/Search issue I emailed about a few weeks back


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives