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

Dear Perl Monks, I have a number, 654848, which is hex 9fe00. I'd like to use the "pack" function to produce what hoepfully will appear as "00 00 00 00 00 09 fe 00" when viewed in emacs with the "hexl-mode" turned on. In using "pack" I need to figure out how to fill with spaces ("\x20") before the actual hex representation of the 654848. Any suggestions?

Replies are listed 'Best First'.
Re: zero fill with pack
by ikegami (Patriarch) on Jun 22, 2010 at 16:48 UTC

    I'd like to use the "pack" function to produce what hoepfully will appear as "00 00 00 00 00 09 fe 00" when viewed in emacs with the "hexl-mode" turned on.

    That's a 64-bit int, so
    pack('q>', $_); # Signed pack('Q>', $_); # Unsigned

    ">" requires 5.10 (IIRC). "q" and "Q" require a 64-bit support. If you don't have a 64-bit support and your numbers aren't "very" large (<232), you could fake it using

    pack('NN', $_<0 ? -1 : 0, $_); # Signed pack('NN', 0, $_); # Unsigned

    In using "pack" I need to figure out how to fill with spaces ("\x20") before the actual hex representation of the 654848. Any suggestions?

    You were talking about converting a number to a native int, now you're talking about its hex representation. It's not clear what you're asking here. Assuming this is a completely separate question,

    sprintf('%8X', $_); # Padded with spaces sprintf('%08X', $_); # Padded with zeros

    Update: Added answer to second question.

      Ikegami, The 'NN' "fake-out" worked nicely. Two things though, I also need to pad the above value with two spaces, i.e., "00 00 00 00 00 09 fe 00 20 20" - need a total byte displacement of ten: how can I pad/add two more spaces at the end of my value? And, what is the significance of the ", 0," in the "pack('NN', 0, $_)" statement? Again, thanks for your prompt response!

        what is the significance of the ", 0," in the "pack('NN', 0, $_)" statement?

        The value for the first "N".

        Q=654848 ----------------------- 00 00 00 00 00 09 fe 00 ----------- ----------- N=0 N=654848

        I also need to pad the above value with two spaces, i.e., "00 00 00 00 00 09 fe 00 20 20"

        More concisely, you want to add two spaces. pack:

        C An unsigned char (octet) value. A A text (ASCII) string, will be space padded.
        pack('NN CC', 0, $_, ord(' '), ord(' ')) pack('NN CC', 0, $_, 0x20, 0x20) pack('NN A2', 0, $_, ' ') pack('NN n', 0, $_, 0x2020)

      Your 32-bit solution is deficient.

      In that it fails for the 9 quadrillion integers between 2**32 ad 2**53 that 32-bit Perls can happily represent.

Re: zero fill with pack
by BrowserUk (Patriarch) on Jun 22, 2010 at 16:46 UTC

    Note: The print unpack 'H*', is just a simulation of hexl-mode. It's the pack bit which does the work:

    print unpack 'H*', pack 'Q>', 654848;; 000000000009fe00 ## With a Perl that doesn't support 64-bit ints (Q). ## Corrected &.v.% per ikegami++ print unpack 'H*', pack 'NN', int( $n / 2**32 ), $n % 0xffffffff;; 000000000009fe00
      $n & 0xffffffff won't work. You need $n % 0xffffffff.

        Works for my (64-bit) Perl ;)