use strict; sub cidr2bits { my $cidr = shift; my $n = $cidr =~ s,/(\d+)$, ? $1 : 32; my @n = $cidr =~ m,\d+,g; substr(unpack("B*",pack("C4", @n,0,0,0,0)),0,$n); } sub bits2cidr { my $bits = shift; my $n = length $bits; $bits .= "0" x 8; join(".", unpack("C*", pack("B*",($bits =~ /^((?:.{8})+?)0*$/)[0])))."/$n"; } sub mergecidr { local $_ = join("\n", sort map { cidr2bits($_) } @_); 1 while s/^(\d*)\n\1.*$/$1/mg || s/^(\d*)0\n\1.$/$1/mg; map { bits2cidr($_) } (!@_ || length($_)) ? split : ''; } #### 10010 100100 100101