In Perl, pack
and unpack
have two templates for converting bytes to/from hex:
h
A hex string (low nybble first).
H
A hex string (high nybble first).
This is best clarified with an example:
use 5.010; # so I can use say
my $buf = "\x12\x34\x56\x78";
say unpack('H*', $buf); # prints 12345678
say unpack('h*', $buf); # prints 21436587
As you can see, H
is what people generally mean when they think about converting bytes to/from hexadecimal. So what's the purpose of h
? Larry must have thought someone might use it, or he wouldn't have bothered to include it.
Can you give a real-world example where you'd actually want to use h
instead of H
with pack
or unpack
? I'm looking for a specific example; if you know of a machine that organized its bytes like that, what was it, and can you link to some documentation on it?
I can think of examples where you could use h
, such as serializing some data when you don't really care what the format is, as long as you can read it back, but H
would be just as useful for that. I'm looking for an example where h
is more useful than H
.
Recall in the bad 'ole days of MS-DOS that certain OS functions were controlled by setting high nibble and low nibbles on a register and performing an Interupt xx. For example, Int 21 accessed many file functions. You would set the high nibble as the drive number -- who will have more than 15 drives?? The low nibble as the requested function on that drive, etc.
Here is some old CPAN code that uses pack as you describe to set the registers to perform an MS-DOS system call.
Blech!!! I don't miss MS-DOS at all...
--Edit
Here is specific source code: Download Perl 5.00402 for DOS HERE, unzip,
In file Opcode.pm and Opcode.pl you see the use of
unpack("h*",$_[0]);
here:I did not follow the code all the way through, but my suspicion is this is to recover info from an MS-DOS system call...
In perlport for Perl 5.8-8, you have these suggested tests for endianess of the target:
It seems that
unpack("h*",...)
is used more often thanpack("h*",...)
. I did note thatreturn qq'unpack("F", pack("h*", "$hex"))';
is used inDeparse.pm
andIO-Compress
usespack("*h",...)
in Perl 5.12If you want further examples, here is a Google Code Search list. You can see
pack|unpack("h*"...)
is fairly rare and mostly to do with determining platform endianess...The distinction between the two just has to do with whether you are working with big-endian or little-endian data. Sometimes you have no control over the source or destination of your data, so the
H
andh
flags to pack are there to give you the option.V
andN
are there for the same reason.I imagine this being useful when transfering data to or reading data from a machine with different endianess. If some process expects to receive data the way it would normally represent it in memory, then you better send your data just that way.