#!perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Deepcopy = 1; $Data::Dumper::Sortkeys = 1; $| = 1; srand(); my $_DEBUG = 0; my %known = ( q{192.168.0.0} => { network => q{192.168.0.0}, mask => q{24}, }, q{192.168.42.128} => { network => q{192.168.42.128}, mask => q{255.255.255.128}, }, q{192.168.127.0} => { network => q{192.168.127.0}, mask => q{255.255.255.0}, }, ); my @test = ( q{192.168.0.1}, q{192.168.42.25}, q{192.168.42.192}, q{192.168.127.0}, q{192.168.127.10}, q{192.168.127.255}, ); my %seen; foreach my $k ( keys %known ) { my $n = str2n( $known{$k}{network} ); my $m; if ( $known{$k}{mask} !~ m/\./ ) { $m = 0xFFFFFFFF << ( 32 - $known{$k}{mask} ); } else { $m = str2n( $known{$k}{mask} ); } $seen{$m}{ $n & $m } = $k; } TESTING: foreach my $ip (@test) { my $i = str2n($ip); foreach my $m ( sort { $b <=> $a } keys %seen ) { my $result = $i & $m; if ( defined( $seen{$m}{ $i & $m } ) ) { my $k = $seen{$m}{$result}; print sprintf qq{%s in %s / %s\n}, $ip, $known{$k}{network}, $known{$k}{mask}; next TESTING; } } print sprintf qq{%s not in provided ranges\n}, $ip; } print Data::Dumper->Dump( [ \@test, \%known, \%seen, ], [qw( *test *known *seen )] ), qq{\n} if ($_DEBUG); sub str2n { print sprintf( qq{\t\t%d %s\n\t\t%d %s\n\t\t%d %d\n}, __LINE__, $_[0], __LINE__, join( q{ }, split /\D/, $_[0] ), __LINE__, unpack( q{N}, pack( q{C4}, split /\D/, $_[0] ), ) ) if ($_DEBUG); return unpack( q{N}, pack( q{C4}, split /\D/, $_[0] ) ); } # Output: # # $ perl test-20140305-01.pl # 192.168.0.1 in 192.168.0.0 / 24 # 192.168.42.25 not in provided ranges # 192.168.42.192 in 192.168.42.128 / 255.255.255.128 # 192.168.127.0 in 192.168.127.0 / 255.255.255.0 # 192.168.127.10 in 192.168.127.0 / 255.255.255.0 # 192.168.127.255 in 192.168.127.0 / 255.255.255.0 #