The "exclusive or" (XOR) function is a logical operation that
compares two boolean values and returns wether or not one of them
(not both, or none) are true.
A |
B |
A B |
True |
True |
False |
True |
False |
True |
False |
True |
True |
False |
False |
False |
Bitwise XOR is done when comparing two bytes (or more) of data,
XOR:ing each bit in one byte with the corresponding bit in the
other byte.
For example:
Let A have the decimal value of 123 and B have the decimal value of
97, and XOR them.
A = 123 decimal, which is 01111011 binary.
B = 97 decimal, which is 01100001 binary.
|
01111011 |
![XOR](http://img.geocaching.com/cache/6f058c1e-81b6-4937-88ea-93acc9403454.jpg) |
01100001 |
|
00011010 |
Bitwise XOR results in 00011010 binary, which is 26 in decimal
notation.
So, 123 XOR 97 is 26.
But let's try 97 XOR 26:
|
01100001 |
![XOR](http://img.geocaching.com/cache/6f058c1e-81b6-4937-88ea-93acc9403454.jpg) |
00011010 |
|
01111011 |
The result (01111011) is now 123 in decimal notation.
So, 123 XOR 97 = 26, and 97 XOR 26 = 123.
As you can see this can be used as a cipher, to code data:
If the value 123 is our message, and 97 is our secret key, we can
XOR 123 and 97, and send the resulting value 26.
The receiver of the message, who knows the secret key, can XOR 26
with the key (97) to obtain the plain text message (123).
This is called an XOR Cipher, which is a relatively simple way of
encrypting a message.
If the cipher key is shorter than the message, the key can be
repeated as needed, but in that case it becomes a polyalphabetic
cipher, and can be broken as such.
However, if the key is as long as the message, and providing that
it is not used more than once, it becomes a one-time pad
encryption, that can not be broken (even in theory - which can be
proven mathematically).
Let's try it out:
We receive a coded message in ten bytes, represented by the
following ten decimal values:
(113, 3, 95, 86, 89, 0, 89, 12, 67, 95)
We know the secret key to be the
seemingly random ASCII text
string "6f058c1e-8". The ASCII numbers of the key are:
(54, 102, 48, 53, 56, 99, 49, 101, 45, 56)
To get the clear text message, we XOR the coded message with the
key, byte by byte, bit by bit.
Byte # |
0 |
1 |
2 |
3 |
4 |
Coded |
01110001 |
00000011 |
01011111 |
01010110 |
01011001 |
Key |
00110110 |
01100110 |
00110000 |
00110101 |
00111000 |
![XOR](http://img.geocaching.com/cache/6f058c1e-81b6-4937-88ea-93acc9403454.jpg) |
01000111 |
01100101 |
01101111 |
01100011 |
01100001 |
(Decimal) |
71 |
101 |
111 |
99 |
97 |
(ASCII) |
G |
e |
o |
c |
a |
Byte # |
5 |
6 |
7 |
8 |
9 |
Coded |
00000000 |
01011001 |
00001100 |
01000011 |
01011111 |
Key |
01100011 |
00110001 |
01100101 |
00101101 |
00111000 |
![XOR](http://img.geocaching.com/cache/6f058c1e-81b6-4937-88ea-93acc9403454.jpg) |
01100011 |
01101000 |
01101001 |
01101110 |
01100111 |
(Decimal) |
99 |
104 |
105 |
110 |
103 |
(ASCII) |
c |
h |
i |
n |
g |
So, the byte sequence (113, 3, 95, 86, 89, 0, 89, 12, 67, 95)
decoded with the key "6f058c1e-8" gives us the message:
"Geocaching".
But where is the plastic box?
I wrote a message containing the coordinates to this cache, in an
8-bit ASCII text string, and encoded the message using an XOR
cipher. The key is just as long as the encrypted text (36
characters/bytes), so it doesn't need to be repeated. I don't
intend to use the key for anything else after this.
The following set of 36 decimal values represents the encoded
data:
(99, 8, 84, 80, 74, 67, 67, 10, 78, 83, 17, 3, 66, 13, 122, 12, 10,
23, 31, 9, 22, 81, 89, 27, 25, 118, 81, 82, 84, 25, 1, 7, 29, 2, 0,
12)