Question

I have some 256-character strings of hexadecimal characters which represent a sequence of bit flags, and I'm trying to convert them back into a bitstring so I can manipulate them with &, |, vec and the like. The hex strings are written in integer-wide big-endian groups, such that a group of 8 bytes like "76543210" should translate to the bitstring "\x10\x32\x54\x76", i.e. the lowest 8 bits are 00001000.

The problem is that pack's "h" format works on one byte of input at a time, rather than 8, so the results from just using it directly won't be in the right order. At the moment I'm doing this:

my $bits = pack("h*", join("", map { scalar reverse $_ } unpack("(A8)*", $hex)));

which works, but feels hackish. It seems like there ought to be a cleaner way, but my pack-fu is not very strong. Is there a better way to do this translation?

Was it helpful?

Solution

my $hex = "7654321076543210";  # can be as long as needed
my $bits = pack("V*", unpack("N*", pack("H*", $hex)));
print unpack("H*", $bits);  #: 1032547610325476

OTHER TIPS

Consider using the excellent Bit::Vector.

Use the hex function to turn the hex string into Perl's internal representation of the number, do your bitwise operations, and use sprintf to turn it back into the hex string:

#!/usr/bin/perl

use strict;
use warnings;

my $hex = "76543210";
my $num = hex $hex;

$num &= 0xFFFF00FF; # Turn off the third byte

my $new_hex = sprintf("%08x", $num);

print "It was $hex and is now $new_hex.\n";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top