1

I have two strings representing hex numbers which I need to make a bitwise comparison of. Each hex number equates to 256 bits. I need to determine how many of the bits are different. How can I do this in perl?

$hash1 = "7ff005f88270898ec31359b9ca80213165a318f149267e4c2f292a00e216e4ef";
$hash2 = "3fb40df88a78890e815251b1fb8021356da330f149266f453f292a11e216e4ee";

My question is similar to this question but I need to do it in perl.

Community
  • 1
  • 1
CJ7
  • 22,579
  • 65
  • 193
  • 321

2 Answers2

3
my $bytes1 = pack('H*', $hash1);
my $bytes2 = pack('H*', $hash2);
my $xor    = unpack('B*', $bytes1 ^ $bytes2);
my $count  = $xor =~ tr/1//;

pack('H*', ...) converts the hex strings into byte strings. The byte strings are then XORed and converted to a bit string with unpack('B*', ...). The tr operator is used to count the number of 1s (different bits) in the bit string.

Or, using the checksum trick described here:

my $bytes1 = pack('H*', $hash1);
my $bytes2 = pack('H*', $hash2);
my $count  = unpack('%32B*', $bytes1 ^ $bytes2);
Community
  • 1
  • 1
nwellnhof
  • 32,319
  • 7
  • 89
  • 113
1
$hash1 =~ s/([a-f0-9][a-f0-9])/unpack('B*',pack('H*',$1))/egi;
$hash2 =~ s/([a-f0-9][a-f0-9])/unpack('B*',pack('H*',$1))/egi;

$count = ($hash1 ^ $hash2) =~ tr/\0//c;
CJ7
  • 22,579
  • 65
  • 193
  • 321
  • Can you explain the code a little? The replacement `s///` seems unecessary. Also, you return the number of bits that are the same. – nwellnhof Oct 13 '16 at 01:18
  • @nwellnhof The first two lines convert the hex to binary. How can that happen if there is not substitution? I have added `/c` to return differences instead. – CJ7 Oct 13 '16 at 01:27