Search code examples
perlpack

Why am I getting unexpected results with pack('H*', ...) with perl 5.12.4 and 5.20.2?


I'm XORing, ($a ^= $b), strings and must express them as hex numbers. I can do this with sprintf but I prefer using pack('H*', ...), if possible. I've packaged test code that expresses the problem with embedded comments. Can anyone explain why the pack('H*', ...) statement is failing? Thanks and regards.

use strict;

my @a = qw(a b c d e f g h);
print "@a\n";
my @b = map ord, @a;
foreach (@b) { print "$_\n" };
print scalar(@b), "\n";
my $pad = pack('H*', @b);   # why doesn't this work????
print "\$pad after pack('H*', \@b) = $pad \t\t # garbage :-(\n";
print length($pad), "\n";
$pad = pack('C*', @b);
print "\$pad after pack('C*', \@b) = $pad \t # correct\n";

$pad =~ s/(.)/sprintf("%x",ord($1))/eg;
print "\$pad after sprintf() = $pad\t # correct :-)\n";

exit(0);

Thanks again.


Solution

  • What result do you actually want?

    The H template for pack expects a hex string and returns a string consisting of the characters at those hex code points. So pack 'H*', '414243' will give you ABC

    At a guess you want the reverse of that, so use unpack like this

    my @a = qw(a b c d e f g h);
    say unpack 'H*', join '', @a;
    

    output

    6162636465666768