I happened to have telephone numbers coming from ASN.1 encoded data translated into HEX (they're represented as BCD), but odd cyphers were swapped with even (e.g. "214365" instead of "123456"), so I found this trick quite useful.

It basically uses pack putting high nybble first, then unpack putting high nybble last to do the trick.

Note that it works only for HEX dumps, i.e. couples of octets in 0-9a-fA-F, so its usefulness is quite limited...

my $start = "214365"; my $final = unpack "h*", pack "H*", $start;

Replies are listed 'Best First'.
Re: Swapping odd-even characters of BCD hex data
by Roy Johnson (Monsignor) on Apr 27, 2005 at 19:38 UTC
    I would probably have used
    (my $final = $start) =~ s/(.)(.)/$2$1/g;
    which has the advantage of displaying a really nice pair.

    Caution: Contents may have been coded under pressure.
      I wasn't sure to post this little snippet, but I've confirmation that I made well. I had come up with something similar to your solution, but I hadn't realised that the "g" modifier would work so excellently in this case. Your solution is more "general", in that it works for non-hex chars.

      For my particular case, anyway, I'll stick to my solution. I made a bit of benchmarking, and my solution is faster for this particular hex application:

      #!/usr/bin/perl -w use strict; use Benchmark qw(cmpthese); sub PackUnpack { unpack "h*", pack "H*", shift; $v; # Thanks Roy! } sub SubstRegex { (my $v = shift) =~ s/(.)(.)/$2$1/g; } my @tests = map { unpack "h*", $_ } qw(ciao a tutti quanti 43242 432423423423 kjlf94324 dfas8902342); cmpthese (-1, { PackUnpack => sub { PackUnpack($_) foreach (@tests) }, SubstRegex => sub { SubstRegex($_) foreach (@tests) }, } ); __END__ Rate SubstRegex PackUnpack SubstRegex 3079/s -- -79% PackUnpack 14463/s 370% --
      This is no surprise, of course - and your solution remains more useful for the general case.

      Update: SubstRegex returns $v as per Roy Johnson's suggestion.

      Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

      Don't fool yourself.