Hi all other monks,

I'm trying to write a hex to binary converter and found what I thought were the needed code nuggets towards the bottom of "perldoc perlpacktut" documentation in the Intel Hex section. It seemed fairly straightforward, but I found that when processing bytes of data that the upper nibble is being dropped during the conversion. The discovery only came by reverse-conversion of the binary output string. The data length is reported as being correct; the first data line has 16 bytes, and the second contains 14 bytes - note this format has 4 bytes of info at the beginning of the line and a checksum byte at the end.

Here is my test code:

#!/usr/bin/env perl use strict; use warnings; use utf8; #===================================================================== +========== # Set to "1" for additional debugging print statements. #===================================================================== +========== my $debug= 1; #===================================================================== +========== # Standard input while loop #===================================================================== +========== my $line; # Retrieve a line while ($line = <DATA>) { # chomp line chomp $line; # Does line begin with ":"? if (($line !~ /^\:/) || ($line =~ /^\$/)) { print "INVALID LINE, SKIPPING : $line\n" if $debug; next } else { # convert line to hex (and strip off ":") my $hexrec = pack( 'H*', substr( $line, 1 ) ); # calculate checksum, if error, die. my $chksum = unpack( "%C*", $hexrec ); print "checksum = $chksum\n" if $debug; die unless unpack( "%8C*", $hexrec ) == 0; # # process the line. get bytecount, address, record type, and d +ata # my( $bytecount, $address, $recordtype, $data ) = unpack( "C n +C X4 C x3 /a", $hexrec ); # note: no reason to print data, since it results in special, +unprintable chars printf ("bytecount = %d, address = %d, recordtype = %d\n", $by +tecount, $address, $recordtype) if $debug; # # terminator line # if ($recordtype == 1) { print "Conversion complete\n"; exit; } # # real data line # elsif ($recordtype == 0) { my $binarycount = $bytecount*8; my $datlength = length($data); print "Data length (should match bytecount) = $datlength\n +"; # convert to binary my $binaryval = unpack("B$binarycount", pack("H$bytecount" +, $data)); print "binary = $binaryval\n" if $debug; } } } # end of while __DATA__ :1004D0000A95E1F7E0E0F8E000E40BBF00E81791CF :0E04E0001D930A95E1F74CCE00E10883FDCE96 :00000001FF __END__

The results of running the Perl code is this:

checksum = 2816 bytecount = 16, address = 1232, recordtype = 0 Data length (should match bytecount) = 16 binary = 1010010100010111000000001000000000000100101111110000100001110 +001 checksum = 2304 + bytecount = 14, address = 1248, recordtype = 0 + Data length (should match bytecount) = 14 + binary = 11010011101001010001011101011110000000011000001111011110 + checksum = 256 + bytecount = 0, address = 0, recordtype = 1 + Conversion complete

If someone can shed some light on this and help me to understand pack/unpack a tiny bit better, it would be much appreciated.

Thanks,

Joe


In reply to Pack or unpack dropping a nibble by smknjoe

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.