Skip to content

Instantly share code, notes, and snippets.

@pen
Created March 18, 2017 00:34
Show Gist options
  • Save pen/ee953de9f894dbbede7907278aaa984a to your computer and use it in GitHub Desktop.
Save pen/ee953de9f894dbbede7907278aaa984a to your computer and use it in GitHub Desktop.
combine subnets
#!/usr/bin/env perl -w
use strict;
package CIDRs {
sub new { bless +{}, shift }
sub add {
my ($self, $cidr) = @_;
my ($ipv4, $w) = split '/', $cidr;
my $b = (hex join '', map { sprintf '%02X', $_ } split /\./, $ipv4) >> 32 - $w;
while (delete $self->{$w}->{$b ^ 1}) { $w--; $b >>= 1 }
++$self->{$w}->{$b};
}
sub list {
my $self = shift;
my @list = map { join('.', map hex, sprintf('%08X', $$_[0]) =~ /../g) . '/' . $$_[1] }
sort { $a->[0] <=> $b->[0] }
map { my $w = $_; map { [ $_ << 32 - $w, $w ] } keys %{$self->{$w}} }
keys %$self;
wantarray ? @list : \@list;
}
}
package main {
my $c = CIDRs->new();
while (<>) {
chomp;
$c->add($_); # '192.168.0.0/24'
}
print "$_\n" for $c->list;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment