#!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 # #### #!perl use strict; use warnings; use Data::Dumper; $| = 1; srand(); my $_DEBUG = 0; my %known = ( 192.168.0.0 => { network => q{192.168.0.0}, mask => q{24}, }, 192.168.42.128 => { network => q{192.168.42.128}, mask => q{255.255.255.128}, }, 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}, ); TESTING: foreach my $ip (@test) { my $i = str2n($ip); print sprintf( qq{%d %s: %d (0x%8x)\n}, __LINE__, $ip, $i, $i, ) if ($_DEBUG); foreach my $k ( keys %known ) { print sprintf( qq{\t%d %s / %s\n}, __LINE__, $known{$k}{network}, $known{$k}{mask}, ) if ($_DEBUG); my ( $m, $n, ); $n = str2n( $known{$k}{network} ); if ( $known{$k}{mask} !~ m/\./ ) { $m = 0xFFFFFFFF << ( 32 - $known{$k}{mask} ); } else { $m = str2n( $known{$k}{mask} ); } print sprintf( qq{\t%d %d / %d\n}, __LINE__, $n, $m, ) if ($_DEBUG); my $n_m = $n & $m; my $i_m = $i & $m; print sprintf( qq{\tTest range: %d / %d\n} . qq{\tnet & mask: %d\n} . qq{ip & mask: %d\nResults: %d\n}, $n, $m, $n_m, $i_m, $i_m == $n_m ) if ($_DEBUG); if ( $n_m == $i_m ) { print $ip, q{ in }, $known{$k}{network}, q{/}, $known{$k}{mask}, qq{\n}; next TESTING; } } print $ip, qq{ not in provided ranges\n}; } 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-00.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 #