bh_perl has asked for the wisdom of the Perl Monks concerning the following question:

Hi.. Actually I am dealing with binary files and I have convert it to hex using pack function. But, some of the values on reverse mode, example:-


- input values is 0x1234567890

- value after reverse is 9078563412

My question is is there any function to reverse on pack function or do i have to reverse for each 2 character ?..

Otherwise, could some body help me how could i reverse each 2 character as above?

Replies are listed 'Best First'.
Re: How to reverse for each 2 character ?
by Corion (Patriarch) on Aug 29, 2008 at 07:20 UTC

    Read pack. Likely you're using the H2 template and it seems you want to use the h2 template instead.

Re: How to reverse for each 2 character ?
by ikegami (Patriarch) on Aug 29, 2008 at 07:41 UTC

    Sounds like you chose the wrong one of unpack('V', $packed), unpack('N', $packed) and unpack('L', $packed).

    printf "%08X\n", unpack 'N', "\x12\x34\x56\x78"; # 12345678 printf "%08X\n", unpack 'V', "\x12\x34\x56\x78"; # 78563412

      is it right command ?

      my $cdrdata = unpack "N*", substr($data, BLOCKHDR+BLOCKDATA, CDRLENGT +H);

      Its look not convert all the hex values, might be my code is wrong..

        unpack "N", $string will take the first 4 bytes of $string and return a 32-bit integer, taking the 4 bytes in "Network" order -- the first byte is the most significant, and then in descending order (ie big-endian).

        unpack, "N*", $string will repeat the process of extracting 32-bit integers to consume all of $string, and returns a list of those integers.

        my $cdrdata = unpack "N*", $string will unpack as many 32-bit integers as there are in $string, and then set $cdrdata to the first of them. Which, on the face of it, isn't what you wanted.

        If the input is little-endian, you need unpack "V", ....

        If the input is not 32-bit integers in one or other order, you need something more general, such as:

        my $foo = reverse(unpack('h*', "\x21\x43\x65\x87\x09\xBA\xDC")), "\n +" ;
        which sets $foo to the string: 1234567890abcd

        You can, of course, replace the * in h* by a number to extract a fixed number of bytes. So '(h6)*' would extract six bytes at a time, as many times as it could.

        I'll leave why this works as homework :-)

        No idea. I don't know the format of your data.
Re: How to reverse for each 2 character ?
by moritz (Cardinal) on Aug 29, 2008 at 07:20 UTC
    $ perl -wle 'print join "", reverse unpack("(A2)*", "1234567890")' 9078563412

    Or you could scalar reverse the binary data before unpacking it, that should give the same result.