Работа с исключающим ИЛИ на битах - что-то, что ясно мне. Но здесь, XOR работает над отдельными символами. Это означает байт, который составляет символ, XORed? На что это похоже?
#include <iostream.h>
int main()
{
char string[11]="A nice cat";
char key[11]="ABCDEFGHIJ";
for(int x=0; x<10; x++)
{
string[x]=string[x]^key[x];
cout<<string[x];
}
return 0;
}
Я знаю биты, XORed похожи на это:
1010
1100
0110
В C и C ++ строки обычно хранятся в памяти как 8-битные символьные значения, где хранимое значение представляет собой ASCII значение символа.
Таким образом, ваш код выполняет операцию XOR для значений ASCII. Например, второй символ в вашем выводе рассчитывается следующим образом:
'B' ^ ' ' = 66 ^ 32 = 01000010 ^ 00100000 = 01100010 = 98 = 'b'
Вы можете получить другой результат, если запустите этот код в системе, которая использует EBCDIC вместо ASCII.
XOR обладает замечательным свойством: если дважды выполнить XOR с одними и теми же данными, вы получите оригинал. Опубликованный вами код представляет собой элементарную функцию шифрования, которая «шифрует» строку с помощью ключа. Полученный зашифрованный текст может быть пропущен через ту же программу для его расшифровки.
Операция xor для символов выполняет операцию xor для каждого соответствующего бита из двух символов (по одному байту каждый).
Значит ли это, что байт, составляющий символ, переписывается?
Именно.
Как это выглядит?
Как и любой другой XOR :) . В ASCII "A nice cat" - это (в шестнадцатеричной системе)
41 20 6E 69 63 65 20 63 61 74
и ABCDEFGHIJ
41 42 43 44 45 46 47 48 49 4A
так что, если вы XOR каждый байт друг с другом, вы получите
00 62 2D 2D 26 23 67 2B 28 3E
, что является шестнадцатеричным представлением "\0b--g+(>", т.е. строка, которая отображается, когда вы выполняете этот код.
Заметьте, что если вы снова сделаете XOR над полученным текстом, то получите обратно тот текст, с которого начали; это причина, по которой XOR часто используется в кодировании и шифровании.
Это простая демонстрация шифрования с помощью одноразового блокнота, который, как вы видите, довольно прост, а также является единственной доказательно невзламываемой формой шифрования. Из-за того, что оно симметрично и имеет ключ размером с сообщение, оно часто непрактично, но все же имеет ряд интересных применений... :-)
Если вы еще не знакомы с ним, обратите внимание на одну интересную вещь - симметрию между ключом и шифротекстом. После их генерации невозможно различить, какой из них какой, т.е. какой из них был создан первым, а какой основан на открытом тексте и ксоре с другим. Помимо базового шифрования это также приводит к применению для правдоподобного отрицания.