use strict; use warnings; my @ips = qw( 1.1.1.1 1.1.1.2 1.1.1.127 1.1.1.128 1.1.1.129 10.1.2.5 10.1.2.6 10.1.2.10 ); my $mask = 25; sub pack_ip4 { return pack 'C4', split /\./, $_ for @_ ? $_[0] : $_} sub unpack_ip4 { return join '.', unpack 'C4', $_ for @_ ? $_[0] : $_} sub sort_ip4 { map unpack_ip4, sort map pack_ip4, @_ } my $packed_mask = pack('B32', ('1'x$mask) . ('0'x(32-$mask))); my %by_net; foreach my $ip (@ips) { my $net = unpack_ip4(pack_ip4($ip) & $packed_mask); push @{$by_net{$net}}, $ip; } foreach my $net (sort_ip4(keys(%by_net))) { print("Network $net/$mask:\n"); foreach my $ip (sort_ip4(@{$by_net{$net}})) { print(" $ip\n"); } print("\n"); } #### Network 1.1.1.0/25: 1.1.1.1 1.1.1.2 1.1.1.127 Network 1.1.1.128/25: 1.1.1.128 1.1.1.129 Network 10.1.2.0/25: 10.1.2.5 10.1.2.6 10.1.2.10