С++ Дешифровщик
"...кодом, соответствующему символу c, является c^key, где key - строка, переданная в качестве параметра командной строки. Программа использует циклически символы из key до тех пор, пока не будет считан весь ввод." Выполнить это задание труда не составило. Вот исходник:
#include <fstream>
#include <cstring>
using std::cout;
using std::cin;
using std::endl;
using std::cerr;
void encoder(const char* k);
void decoder(const char* k, const char* f);
int main(int argc, char** argv)
{
char* key;
char* filename;
int len;
switch (argc)
{
case 1:
cerr << "Missing arguments list!\n"
<< "Usage:\tapp_name coding_key [filename_to_decode]\n";
break;
case 2:
len = strlen(argv[1]);
key = new char[len + 1];
strcpy(key, argv[1]);
encoder(key);
delete [] key;
break;
case 3:
len = strlen(argv[1]);
key = new char[len + 1];
strcpy(key, argv[1]);
len = strlen(argv[2]);
filename = new char[len + 1];
strcpy(filename, argv[2]);
decoder(key, filename);
delete [] key;
delete [] filename;
break;
default:
cerr << "Too many arguments!"
<< "Usage:\tapp_name coding_key [filename_to_decode]\n";
break;
}
return 0;
}
void encoder(const char* k)
{
std::ofstream fout;
cout << "Enter text for encoding:\n";
char ch;
int code;
int i = 0;
fout.open("code.txt");
while ((ch = cin.get()) != '\n')
{
if (k == '\0') i = 0;
code = static_cast<int> (ch ^ k);
fout << ' ' << code;
++i;
}
fout.close();
cout << endl;
}
void decoder(const char* k, const char* f)
{
std::ifstream fin;
cout << "Decoding text:\n";
int i = 0;
char ch;
int code;
fin.open(f);
if (!fin.is_open())
{
cerr << "File not found!\n";
return;
}
while (fin.good())
{
fin >> code;
if (k == '\0') i = 0;
ch = code ^ static_cast<int> (k);
cout << ch;
++i;
}
cout << endl;
}
Программа работает корректно, если у кого-то есть замечания по реализации - охотно выслушаю. Однако, вопрос не в этом. В следующем задании Страуструп предлагает написать программу дешифровки сообщений, созданных описанным способом, не зная ключа. Я прежде никогда не имел опыта создания подобных дешифраторов, посему не знаю даже с чего начать. Попробовал почитать рекомендованную автором книгу Дэвида Кана "Взломщики кодов" и пришел к выводу, что взломать этот код под силу только профессионалам. Если кого-нибудь эта тема заинтересует - в прилагаемом файле содержится зашифрованная фраза. У кого какие мысли на сей счет?
Но в таком случае очень сложно её расшифровать, так как, во-первых, используется многоалфавитная подстановка, а во-вторых, длина строки очень малая для того, чтобы можно было хоть как-то применить частотный анализ.
Если же забыть про этот файл, и принять за данность, что шифротекст будет большой, то всё достаточно просто: сначала следует вычислить длину ключа (количество символов в строке key), а потом отдельно для каждой группы символов применить ЧА. Символы по группам бьются согласно длине ключа, например: длина ключа 3, шифровка ABCDEFGHIJK, тогда будет 5 групп: (ADGJ), (BEHK), (CFI).
Для начала можно попробовать решить задачу, если мы знаем, что длина ключа - один символ. Тут можно цепляться за пробелы и наиболее часто встречающиеся гласные.
Как это сделать? Сразу в голову не приходит.
"...кодом, соответствующему символу c, является c^key, где key - строка, переданная в качестве параметра командной строки. Программа использует циклически символы из key до тех пор, пока не будет считан весь ввод." Выполнить это задание труда не составило. Вот исходник:
#include <fstream>
#include <cstring>
using std::cout;
using std::cin;
using std::endl;
using std::cerr;
std::ifstream fin;
std::ofstream fout;
void encoder(const char* k);
void decoder(const char* k, const char* f);
int main(int argc, char** argv)
{
char* key;
char* filename;
int len;
switch (argc)
{
case 1:
cerr << "Missing arguments list!\n"
<< "Usage:\tapp_name coding_key [filename_to_decode]\n";
break;
case 2:
len = strlen(argv[1]);
key = new char[len + 1];
strcpy(key, argv[1]);
encoder(key);
delete [] key;
break;
case 3:
len = strlen(argv[1]);
key = new char[len + 1];
strcpy(key, argv[1]);
len = strlen(argv[2]);
filename = new char[len + 1];
strcpy(filename, argv[2]);
decoder(key, filename);
delete [] key;
delete [] filename;
break;
default:
cerr << "Too many arguments!"
<< "Usage:\tapp_name coding_key [filename_to_decode]\n";
break;
}
return 0;
}
void encoder(const char* k)
{
cout << "Enter text for encoding:\n";
char ch;
int code;
int i = 0;
fout.open("code.txt");
while ((ch = cin.get()) != '\n')
{
if (k == '\0') i = 0;
code = static_cast<int> (ch ^ k);
fout << ' ' << code;
++i;
}
fout.close();
cout << endl;
}
void decoder(const char* k, const char* f)
{
cout << "Decoding text:\n";
int i = 0;
char ch;
int code;
fin.open(f);
if (!fin.is_open())
{
cerr << "File not found!\n";
return;
}
while (fin.good())
{
fin >> code;
if (k == '\0') i = 0;
ch = code ^ static_cast<int> (k);
cout << ch;
++i;
}
cout << endl;
}
Программа работает корректно, если у кого-то есть замечания по реализации - охотно выслушаю. Однако, вопрос не в этом. В следующем задании Страуструп предлагает написать программу дешифровки сообщений, созданных описанным способом, не зная ключа. Я прежде никогда не имел опыта создания подобных дешифраторов, посему не знаю даже с чего начать. Попробовал почитать рекомендованную автором книгу Дэвида Кана "Взломщики кодов" и пришел к выводу, что взломать этот код под силу только профессионалам. Если кого-нибудь эта тема заинтересует - в прилагаемом файле содержится зашифрованная фраза. У кого какие мысли на сей счет?
это гамирование + хор, то бишь наложение на шифруемое сообщение некой гаммы через операцию xor. ищите в сети и курите мануалы по гамированию, ломается данный метод "шифрования" на ура.
замечания по коду: глобальные переменные не есть хорошо, приведение типов не есть хорошо. в целом нормально. особо придираться не буду.
замечания по коду: глобальные переменные не есть хорошо, приведение типов не есть хорошо.
Абсолютно согласен по глобальным переменным - сейчас поправлю. Тем более, что в данном случае в них не было никакой необходимости. По поводу приведения - пока не понимаю, как без него обойтись. Приведением пришлось воспользоваться в процессе отладки, т.к. я хотел получить в шифрованном тексте не символы-кракозябы, а числа.
За термин "гаммирование" - плюс. За "ломаются на ура" - минус. В статье (по ссылке) говорится, что Шеннон доказал, что шифр может быть абсолютно стойким, то есть, как я понимаю - нерасшифровываемым.
По поводу длины ключа и длины открытого текста в условии ничего не сказано, но в данном случае я использовал ключ значительно меньшей длины, чем текст (но и не из одной буквы).
Я предлагаю идти от простого к сложному. Если с одной буквой решим, то будет какой-то опыт, какие-то зацепки. Хотя можно конечно и погуглить, но это не так интересно, не так понятно, когда не пытался изобрести свой велосипед :)
Спасибо за проявленный к моей теме интерес. Вопрос на самом деле оказался сложным и ответить на него вряд ли удасться за короткий промежуток времени. Буду искать, пробовать. Если получится что-нибудь - отпишусь непременно.
они стойкие только в случае, если для гаммы используется абсолютно случайная бесконечная последовательность, что фактически не реально. Так же "стойкость" может быть достигнута при проведении нескольких раундов гаммирования, что так же весьма сомнительно, ведь в понятие стойкости помимо всего прочего входит условие известности алгоритма шифрования взломщику. Да и вообще к слову, гаммирование уже давно не используется самостоятельно, а лишь как составной элемент более надежной системы шифрования. Минус не принимается. :) Да и плюс тоже, не за что. :)
Прежде чем накодить, хочу услышать мнение экспертов - стоит ли овчинка выделки? Или нужно искать другие решения?
Насколько я понял, достаточно, если гамма (или ключ в терминологии темы) будет длиннее зашифрованного текста.
Думаю, тут есть одна проблема. Возьмём фантастический случай - получили последовательность из существующих слов, но это не тот текст, это набор слов. Может такое быть? Почему нет?
Или, например, совпали только некоторые слова с теми, что в списке. Можно ли такое отправить человеку?
Возможно, придётся выдавать человеку список наиболее удачных расшифровок, чтобы он выбрал правильную по смыслу.
Возможно, придётся выдавать человеку список наиболее удачных расшифровок, чтобы он выбрал правильную по смыслу.
Так я это и имел ввиду: