Your update helped clarify one particular thing here. A little post-processing can help set things straight. Since all the data is stored in organized structures, it can be cleaned up before being printed out. In this case, joining adjacent blocks is a no-brainer.

The idea is that since IP addresses are just numbers, you can do math on them to add and subtract. In this case, what you want to do is add one to the "end" to see if it matches the next "start". You could write your own add function, but this is a little tedious, with up to three possible carries. Instead, it is much more efficient to render the IP address as a simple 32-bit number and work with it that way. This can be done with unpack which will extract the "raw" 32-bit value of an inet_aton operation. A "N"-type pack is a network-order 32-bit number, a standard way of transporting numbers across the Internet.

So, once unpacked, you add one, and feed the result back into inet_aton which will give you a new repacked address. This can be extracted, if you like, into the pretty human-readable version we've come to know, using inet_ntoa.

This code merely compares the data in the hash for any adjacent matches, and when it finds them, puts the end from the second as the end of the first, and deletes the second.
# 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; } } }
This is just off the top, so your mileage may vary.

In reply to Re: IP Address consolidation by tadman
in thread IP Address consolidation by yasysad

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.