понедельник, 9 января 2012 г.

Простое XOR-шифрование. Алгоритм.

Коротенько расскажу тебе про XOR-шифрование с маленьким примером.

Итак, основная идея алгоритма состоит в том, что если у нас есть некая величина, есть некий шифровальный ключ (другая величина), то можно зашифровать исходные данные через этот ключ, применив операцию XOR побитно. Т.е. если у нас есть исходная фраха a и ключ k, то x = a ^ k. Теперь, если к шифру x опять применить ключ, то получим исходную фразу, т.е. a` = x ^ k, где a` = a.

Вот принцип в простом примере:

#include <iostream>
using namespace std;
int main()
{
  // Кодируемая информация
 const int Source = 333;
  // Ключ шифрования
 const int Key=5;

 int coded = Source ^ Key;
  int decoded = coded ^ Key;

 cout << "Source data: " << Source << endl << endl;
 cout << "Code key: " << Key << endl << endl;
 cout << "Coded: " << coded << endl<< endl;
 cout << "Decoded: " << decoded << endl<< endl;

  system("PAUSE");
 return 0;
 }

Попробуй и оцени. Вместо нашего числа в шифровке появляется некое "не наше". И опять возвращается исходное число. Теперь попробуем по-сложнее, кодировать более крупные объекты:

#include <iostream>
using namespace std;
int main()
{
  // Исходная строка
 const char SourceText[] = "Hello, World!";
 // Ключ шифрования
 const char Key[] ="key";

  // Строка под шифровку
 char coded[] = new char[strlen(SourceText)+1];
 coded[strlen(SourceText)] = '';

 // Процесс шифрования
 //-------
  for (int i=0,j=0; i<(int)strlen(SourceText); i++,j++)
 {
    if ( !(j<(int)strlen(Key)+1) )
      j=0;
   coded[i] = SourceText[i] ^ Key[j];
 }
 //-------
  // Строка под дешифрованное сообщение
  char* decoded = new char[strlen(SourceText)+1];
  decoded[strlen(SourceText)] = '';

 // Процесс дешифровки
 //-------
  for (int i=0,j=0; i<(int)strlen(SourceText); i++,j++)
 {
    if ( !(j<(int)strlen(Key)+1) )
      j=0;
   decoded[i] = coded[i] ^ Key[j];
  }
  //-------

 cout << "Source string: " << SourceText << endl << endl;
 cout << "Code key: " << Key << endl << endl;
 cout << "coded: " << coded << endl<< endl;
 cout << "Decoded: " << decoded << endl<< endl;

  delete [] coded;
 delete [] decoded;
 system("PAUSE");
 return 0;
 }

Почему во второй раз я использовал ключ-фразу? Проблема в том, что если ты будешь кодировать одним значением (цифрой, например), то ее будет легко вычислить. Например, по "абракадабрам" вывода сообщения с закодированным текстом, к примеру, можно будет понять какие символы повторяются. Таким образом мы поймем и узнаем где пробелы, повторяющиеся предлоги, знаки пунктуации. Узнав код пробела, не трудно будет вычислить узнать ключ. Если кодовая фраза длинная, то мы стремимся к тому, чтобы у одного и того же байта было как можно больше вариантов в шифрованном виде.

З.Ы.

Было бы круто, если бы ключ был таким же или чуть короче, чем шифруемая информация! И, да, тебе никто не запрещает таким образом шифровать любую информацию: картинки, звуковые файлы, видео, объекты, абстракции программы и т.п.

2 комментария: