Logical XOR produces 1 when exactly one corresponding input bit is 1, and 0 when both bits match. For strings, XOR operates byte by byte by treating each byte as an integer. section 10.11.3
XOR on two bytes
The byte for "a" is 97, or 1100001 in binary; # is 35, or 100011. Computing 97 ^ 35 produces 66, or 1000010. Applying ^ 35 to 66 returns 97, because XOR-ing the same value twice restores the original. section 10.11.3
Listing 10.6 An exclusive-or method for strings
class String
def ^(key) 1
kenum = key.each_byte.cycle 2
each_byte.map {|byte| byte ^ kenum.next }.pack("C*") 3
end
end
A Ruby String#^ method cycles through a key's bytes, XORs them with the receiver's bytes, and packs the results back into a string. section 10.11.3
>> str = "Nice little string."
=> "Nice little string."
>> key = "secret!"
=> "secret!"
>> x = str ^ key
=> "=\f\x00\x17E\x18H\a\x11\x0F\x17E\aU\x01\f\r\x15K"
>> orig = x ^ key
=> "Nice little string."
XOR-ing "Nice little string." with "secret!" produces an obfuscated string; applying the same operation again recovers the original. section 10.11.3


