Skip to content

Instantly share code, notes, and snippets.

@bAndie91 bAndie91/cidr2regex
Last active Apr 25, 2018

Embed
What would you like to do?
converts CIDR to regexp
#!/usr/bin/env perl
use Number::Range::Regex;
Number::Range::Regex->init({'comment'=>0, 'no_leading_zeroes'=>1, 'no_sign'=>1});
$rr0_255 = range(0, 255);
$rr0_32 = range(0, 32);
$union_range = range(-1, -1);
sub hn2dotdec
{
return join '.', unpack 'C4', pack 'N', $_[0];
}
sub dotdec2hn
{
return unpack 'N', pack 'C4', split /\./, $_[0];
}
sub range2regex
{
my $min = shift;
my $max = shift;
my $ddmin = hn2dotdec $min;
my $ddmax = hn2dotdec $max;
my @ddmin = split /\./, $ddmin;
my @ddmax = split /\./, $ddmax;
my @octets;
for my $octet (0..3)
{
if($ddmin[$octet] == $ddmax[$octet])
{
push @octets, $ddmin[$octet];
}
elsif($ddmin[$octet] == 0 and $ddmax[$octet] == $octet_max)
{
push @octets, '';
last;
}
else
{
push @octets, range($ddmin[$octet], $ddmax[$octet])->regex;
}
}
return '^' . join('\.', @octets) . ($octets[-1] eq '' ? '' : '$');
}
while(<>)
{
s/[\r\n]+$//;
my $cidr = $_;
if($cidr !~ /^($rr0_255\.$rr0_255\.$rr0_255\.$rr0_255)\/($rr0_32)$/)
{
warn "not a cidr: $cidr\n";
next;
}
my ($netip, $mask) = ($1, $2);
my $af_length = 32;
my $octet_max = 255;
my $min = dotdec2hn($netip) & (0xFFFFFFFF << ($af_length - $mask));
my $max = $min + 2**($af_length - $mask) - 1;
#my $bmin = reverse pack('I', $min);
#my $bmax = reverse pack('I', $max);
$union_range = $union_range->union(range($min, $max));
my $re = range2regex($min, $max);
print $re, "\n";
}
print STDERR "Merged ranges:\n";
$ranges_str = substr $union_range, 3;
for my $range (split /,/, $ranges_str)
{
my ($min, $max) = $range =~ /(\d+)\.\.(\d+)/;
print range2regex($min, $max), "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.