Reputation: 541
Suppose I have two strings in perl
$a = "10001";
$b = "10101";
I need to find bitwise xor of these two strings i.e.
$a XOR $b = "00100";
How should I do this in perl ?
Upvotes: 1
Views: 10816
Reputation: 385655
To xor two numbers:
my $n1 = 0b10001;
my $n2 = 0b10101;
my $n = $n1 ^ $n2;
say sprintf '%05b', $n;
To xor two numbers (starting from string form):
my $n1 = '10001';
my $n2 = '10101';
my $len = max map length, $n1, $n2;
my $n = oct("0b$n1") ^ oct("0b$n2");
say sprintf '%0*b', $len, $n;
To xor two strings: (any length, as long as it's the same for both strings):
my $n1 = '10001';
my $n2 = '10101';
my $n = ($n1 ^ $n2) | ("\x30" x length($n1));
say $n;
To xor two strings: (any length):
my $n1 = '010001';
my $n2 = '10101';
my $len = max map length, $n1, $n2;
$n1 = substr((" " x $len).$n1, -$len);
$n2 = substr((" " x $len).$n2, -$len);
my $n = ($n1 ^ $n2) | ("\x30" x $len);
say $n;
Upvotes: 4
Reputation: 10234
As far as $a and $b have a fixed length, say 5:
$a = '00011';
$b = '00110';
$xor = ($a ^ $b) | '00000';
Upvotes: 0
Reputation: 15968
If you are declaring the information yourself, you can use a bit literal:
my $first = 0b10001;
my $second = 0b10101;
my $xored = $first ^ $second;
if ($xored == 0b00100)
{
print "Good!";
}
Works with numbers and hex too:
my $first = 21; # or 0b10101 or 0x15
my $second = 0x11; # or 0b10001 or 17
my $xored = $first ^ $second;
if ($xored == 0b00100) # or == 4, or == 0x04
{
print "Good!";
}
As an aside, you should also avoid using $a
and $b
, as they have a special meaning for the sort
function.
Upvotes: 2
Reputation: 118118
Use oct:
If EXPR starts off with
0b
, it is interpreted as a binary string.
#!/usr/bin/env perl
my ($x, $y) = map oct "0b$_", qw(10001 10101);
printf "%08b\n", $x ^ $y;
Upvotes: 3
Reputation: 11744
Use this subroutine:
sub bin2dec {
return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}
It will convert the strings to integers, and you can use the bitwise XOR ^
on them, then test if that equals 4.
Upvotes: 1
Reputation: 5619
You could write a few functions that does the one-bit operation:
sub xor
{
my $p = shift;
my $q = shift;
return ( $p eq $q ) "0" : "1";
}
then you could call this successfully for each pair of characters (each successive bit).
for (my $index = 0; $index < inputLength; $index++)
{
$result = $result . xor ( substr ($a, $index, 1), substr ($b, $index, 1) );
}
Where inputLength
is the length of $a
and $b
.
This is one way of doing it. Hope this helps!
Upvotes: 0