Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
There's more than one way to do things

Convert to Hexadecimal

by Anonymous Monk
on May 17, 2012 at 17:07 UTC ( #971125=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Currently in Perl 5.10.1 I succeeded in denting the wall with my head trying to perform a rather simple task. Starting with a simple ASCII string I need to

- find its length
- convert the length into 2 hex bytes.

my $string = "39860000NO00"; my $length = length($string);
I need to convert the length (12) to the string "\x00\x0c"
any help will be greatly appreciated.

Comment on Convert to Hexadecimal
Download Code
Re: Convert to Hexadecimal
by afoken (Parson) on May 17, 2012 at 17:11 UTC

    See perlpacktut


    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Convert to Hexadecimal
by davido (Archbishop) on May 17, 2012 at 18:03 UTC

    unpack or sprintf to get the hex digits. The substitution operator to match the hex digits, prepending each pair with the literal '\x'.

    my $string = "39860000N000"; my $hexlen = sprintf( '%4.4x', length $string ) =~ s/ ( \p{Hex}{2} ) / +\\x$1/grx; print "Length of ($string) in hex: ($hexlen)\n";

    In older versions of Perl that didn't have the /r flag you would probably want to break that into a couple of statements (and may still wish to do so for clarity's sake):

    my $string = '39860000N000'; my $hexlen = sprintf '%4.4x', length $string; $hexlen =~ s/ ( \p{Hex}{2} ) /\\x$1/gx; print "Length of ($string) in hex: ($hexlen)\n";


      Forever grateful!

      Works like a charm. It will take me some time to understand it though.

      $hexlen = printf("\\x%02x\\x%02x", unpack("C2", pack("n", length($string)));

      (Explanation in reply to OP.)

      "My two cents aren't worth a dime.";
Re: Convert to Hexadecimal
by sauoq (Abbot) on May 17, 2012 at 19:00 UTC

    As davido points out, sprintf() would be almost good enough on its own.

    $ perl -le 'printf( "%04x\n", 12)' 000c

    And, as he points out, you can get the rest of the way with s///. That's pretty ugly though. You could also get there a few other ways... but they are all pretty ugly.

    It would be nice if you could have something like

    perl -le 'printf( "\\x%02x\\x%02x\n", 12 )' # WRONG \x0c\x00

    Unfortunately, "12" is one argument, not two. But that's where unpack comes in handy. You want to unpack a number into two (char sized) values. That leads you to

    perl -le 'printf( "\\x%02x\\x%02x\n", unpack( "C2", 12 ))' WRONG \x31\x32

    But that's wrong too as 12 is a scalar and gets unpacked (by that) as "1", "2" (ASCII 0x31 and 0x32 respectively.) And this is where pack is useful. You want to pack that 12 into a single value before unpacking it into two. Two characters is a short...

    perl -le 'printf( "\\x%02x\\x%02x\n", unpack( "C2", pack("S", 12)))' \x0c\x00

    Oops. Still not quite right. My architecture is little-endian (x86). But that's okay, we can force pack to give us a big-endian short.

    perl -le 'printf( "\\x%02x\\x%02x\n", unpack( "C2", pack("n", 12)))' \x00\x0c # Another way to say that . . . perl -le 'printf( "\\x%02x\\x%02x\n", unpack( "C2", pack("S>", 12)))' \x00\x0c

    It might not be beautiful, but I think it's better than futzing about with string operations after the conversion to hex. Of course, if you read perlpacktut as suggested, I'm sure you've come to this solution already! ;-)

    "My two cents aren't worth a dime.";
Re: Convert to Hexadecimal
by ikegami (Pope) on May 17, 2012 at 19:12 UTC
    Hex is text. «2 hex bytes» makes no sense. You actually want «2 bytes equal to "\x00\x0C"», and that's obtained using
    pack('n', length($string))

    You might also be interested in the following:

    pack('n/a*', $string)

    It's short for

    pack('n', length($string)) . $string

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://971125]
Approved by marto
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (9)
As of 2014-04-19 13:57 GMT
Find Nodes?
    Voting Booth?

    April first is:

    Results (481 votes), past polls