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

..having tried to understand all the Perl format parameters, I have the following hex: '000000000000174f0100000000004a000000000000004a' which is supposed to translate to '0 5976 74 74'. It's formatted as an 'unsigned long long' but I can't seem to figure out the correct unpack options to do this.... ..thanks for the wisdom...

Replies are listed 'Best First'.
Re: reading packed unsigned long long
by ikegami (Patriarch) on Jul 14, 2009 at 15:35 UTC

    It was brought to my attention that despite your use of singular, the hex string should contain 4 numbers. That makes more sense, but your input is still messed up.

    "unsigned long long" is not very descriptive. Even saying "C's unsigned long long" is not very descriptive. That simply means they are at least 64-bit and says nothing of byte order.

    It seems you want to unpack unsigned 64-bit integers in native or network byte order.

    my @vals = unpack('Q*', pack('H*', "000....")); # Native byte order my @vals = unpack('Q>*', pack('H*', "000....")); # Network byte order

    ">" requires Perl 5.10
    "Q" requires a build of Perl that can actually hold 64-bit integers.

      I found out a little bit more about that HEX representation: ..turns out that the last two fields are six bytes and eight bytes (00000000004a/000000000000004a) equalling a decimal 74. I guess I really need to know the correct combination of format characters (e.g., 'NNCNN' - I've tried the "Q" option which my system rejects)....

        Rejected how? "Invalid type 'Q' in unpack"? Note the comment at the bottom of my previous post. Your Perl can't handle 64-bit numbers because your processor can't handle them natively. You could build a Perl that supports 64-bit numbers (even if your processor doesn't handle them natively), or you could use Math::BigInt to hold such a big number. I'll even code the solution if you tell me which byte ordering you want to use.

        turns out that the last two fields are six bytes and eight bytes

        There's no unpack specifier for reading 6-byte ints. j and J might be 6-bytes on your machine, but I'd be surprised. Nobody uses 6-byte ints. That's part of why I said your data is messed up.

        You expect To get that What you have ---------------- ---------------- ---------------- 0 0000000000000000 5967* 000000000000174f 000000000000174f 74 000000000000004a 0100000000004a 74 000000000000004a 000000000000004a

        * — You actually said 5976. I presume that's a typo.

Re: reading packed unsigned long long
by ikegami (Patriarch) on Jul 14, 2009 at 14:00 UTC

    The hex string you posted has 184 bits. That's 120 bits too many for the usual length of a C long long.

    Furthermore, 59,767,474 would be ...00038FFAB2, but that doesn't appear anywhere in your input.

      ..sorry for the confusion - these are supposed to be separate values: 0, 5976, 74, 74