Reputation: 181
I am trying to do bitwise xor 2 ASCII strings of the same length in ruby. I have come to the following:
'A'.unpack('B*').zip('B'.unpack('B*')).map{|a, b| (a.to_i ^ b.to_i).to_s}.pack('b*')
=> "\003"
It works. However, when performing string of 2 or more chars, it behaves wierdly, i think because of the value is too big for Fixnum, see below:
'AA'.unpack('B*').zip('BB'.unpack('B*')).map{|a, b| (a.to_i ^ b.to_i).to_s}.pack('b*')
=> "_\003"
If I stop right after the xor, without the to_s part, I see that it is not doing the bitwise XOR correctly:
'AA'.unpack('B*').zip('BB'.unpack('B*')).map{|a, b| (a.to_i ^ b.to_i)}
=> [1515925259]
Can someone help? Or can someone suggest another way of doing this? Many thanks
Upvotes: 2
Views: 425
Reputation: 20786
I think you want to unpack
with C
(8-bit unsigned) rather than B
(bit string) since the xor operator ^
operates on numbers rather than strings:
'AA'.unpack('C*').zip('BB'.unpack('C*')).map { |a,b| a^b }.pack('C*')
# => "\x03\x03"
3 is what one would expect from xoring 65 ('A'
) with 66 ('B'
).
Upvotes: 2