This is code I wrote to test an idea to solve the problem Dominus posted in Challenge Problem: Merging Network Addresses. The benchmark shows an order of magnitude speed increase over using Net::CIDR, as I had originally suggested. And it's an unusual (ab-)use of the regex engine. Enjoy.
(Yes, I'm writing a column about my findings. {grin})
#!/usr/bin/perl -w use strict; $|++; use Socket qw(inet_aton inet_ntoa); sub cidr2bits { my $cidr = shift; my ($addr, $maskbits) = $cidr =~ /^([\d.]+)\/(\d+)$/ or die "bad format for cidr: $cidr"; substr(unpack("B*", inet_aton($addr)), 0, $maskbits); } sub bits2cidr { my $bits = shift; inet_ntoa(pack "B*", substr("${bits}00000000000000000000000000000000", 0, 32)) . "/" . length($bits); } sub mergecidr { local $_ = join "", sort map { cidr2bits($_)."\n" } @_; 1 while s/^(\d+)0\n\1[1]\n/$1\n/m or s/^(\d+)\n\1\d+\n/$1\n/m; map bits2cidr($_), split /\n/; } my @first = qw( 209.152.214.112/30 209.152.214.116/31 209.152.214.118/31 ); my @second = qw( 209.152.214.112/30 209.152.214.116/32 209.152.214.118/31 ); my @third = qw( 209.152.214.112/31 209.152.214.116/31 209.152.214.118/31 ); if (1) { print join "----\n", map join("", "from:\n", map(" $_\n", @$_), "to:\n", map(" $_\n", mergecidr(@$_))), \@first, \@second, \@third; }
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Merge CIDRs
by gbarr (Monk) on Oct 13, 2001 at 04:31 UTC | |
by merlyn (Sage) on Oct 13, 2001 at 05:24 UTC | |
Re: Merge CIDRs
by Dominus (Parson) on Oct 13, 2001 at 20:50 UTC | |
by merlyn (Sage) on Oct 15, 2001 at 05:44 UTC | |
by Dominus (Parson) on Oct 15, 2001 at 09:50 UTC |
Back to
Cool Uses for Perl