Here is an approach you might like: no loops in evidence (they're hidden in unpack)...

use strict; use warnings; use Data::Dumper; $Data::Dumper::Useqq = 1; # Here is the header value given my $hex = "0001000000004f914f1c0b0100425343413030000000050000434130303 +030300000000143413030303134000000024341303030323200000003434130303032 +3400000004434130303032390000000100224e43656c6c30000000020042534341303 +100000005000543413031303031000000064341303130303400000007434130313031 +30000000084341303130313500000009434130313031360000000100224e43656c6c3 +0000000030042534341303200000006000a"; # It appears to be incomplete, specifying 11 BSC blocks but only # containing two, and an initial fragment of a third. So, pad it. $hex .= "00" x 200; # As the given data is hex, pack it to get a byte string my $header = pack('H*', $hex); # And lets have a look at that byte string print Dumper($header); # # The specification for the header is: # # Header Record Id : 1 Byte # File Format Version : 1 Byte # Timestamp : 8 Bytes # No. of BSCs : 1 Byte # For each BSC ... # BSC Id : 1 Byte # Application Version : 1 Byte # BSC Name : 2 Bytes # Number of Cells : 2 Bytes # For each Cell ... # Cell Pointer : 2 Bytes # Cell Name : 9 Bytes # Number of Neighbour Cells : 2 Bytes # For each Neighbour Cell to this BSC ... # Cell Pointer : 2 Bytes # Cell Name : 9 Bytes # # # But, this doesn't stay in sync with the patterns evident # in the given data. In particular, each cell appears to # be represented in 11 bytes, and the neighbour cells # appear to follow the cells, rather than being nested # within the cells. # # It looks more like # # Header Record Id : 1 Byte # File Format Version : 1 Byte # Timestamp : 8 Bytes # No. of BSCs : 1 Byte # For each BSC ... # BSC Id : 1 Byte # Application Version : 1 Byte # BSC Name : 9 Bytes # Number of Cells : 2 Bytes # For each Cell ... # Cell Pointer : 2 Bytes # Cell Name : 9 Bytes # Unknown Byte # Number of Neighbour Cells : 2 Bytes # For each Neighbour Cell to this BSC ... # Cell Pointer : 2 Bytes # Cell Name : 9 Bytes # # This can be scanned as follows: # my @results = unpack ("C C H16 C X C/( C C a9 C X C/( n a9 ) C C X C/(n a9) )", +$header); # And, we what we get out of it print "Results:\n" . Dumper(\@results) . "\n";

This produces the following output:

$VAR1 = "\0\1\0\0\0\0O\221O\34\13\1\0BSCA00\0\0\0\5\0\0CA00000\0\0\0\1 +CA00014\0\ 0\0\2CA00022\0\0\0\3CA00024\0\0\0\4CA00029\0\0\0\1\0\"NCell0\0\0\0\2\0 +BSCA01\0\0 \0\5\0\5CA01001\0\0\0\6CA01004\0\0\0\aCA01010\0\0\0\bCA01015\0\0\0\tCA +01016\0\0\ 0\1\0\"NCell0\0\0\0\3\0BSCA02\0\0\0\6\0\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +0\0\0\0\0\ 0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +0\0\0\0\0\ 0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +0\0\0\0\0\ 0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +0\0\0\0\0\ 0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +0\0\0\0\0\ 0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; Results: $VAR1 = [ 0, 1, "000000004f914f1c", 11, 1, 0, "BSCA00\0\0\0", 5, 0, "CA00000\0\0", 1, "CA00014\0\0", 2, "CA00022\0\0", 3, "CA00024\0\0", 4, "CA00029\0\0", 0, 1, 34, "NCell0\0\0\0", 2, 0, "BSCA01\0\0\0", 5, 5, "CA01001\0\0", 6, "CA01004\0\0", 7, "CA01010\0\0", 8, "CA01015\0\0", 9, "CA01016\0\0", 0, 1, 34, "NCell0\0\0\0", 3, 0, "BSCA02\0\0\0", 6, 10, "\0\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0, 0, 0, "\0\0\0\0\0\0\0\0\0", 0, 0, 0 ];

While it is possible to use grouping and repeat counts in unpack to scan headers such as these, I don't find the resulting array to be very useful. I would use loops myself, and build a more accessible data structure. None the less, you might use this approach and adjust as necessary to accommodate whatever the exact structure of your header records is. This is, at least, a working example with somewhat reasonable looking results from the given data.


In reply to Re^5: Handling Hex data with Dynamic unpack by ig
in thread Handling Hex data with Dynamic unpack by PerlJedi

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.