# This function returns the 32-bit value # of the IP address for numeric comparisons. sub addr_value { return unpack("N", $_[0]); } foreach my $name (sort keys %data) { my $carry; foreach my $start (sort keys %{$data{$name}}) { # Skip keys deleted after keys was calculated next unless defined $data{$name}{$start}; # Add one to the end to determine the next start my $next_start = inet_aton(addr_value($end)+1); # If this block is adjacent to the next one... if (defined $data{$name}{$next_start}) { $carry ||= $start; # ...end this block where that block ended... $data{$name}{$carry} = $data{$name}{$next_start}; # ...and delete that block. delete $data{$name}{$next_start}; } else { # No match, so reset the $carry undef $carry; } } }