Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2016
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.32 KB | None | 0 0
  1. #include<iostream>
  2. #include<fstream>
  3. #include<string>
  4. #include<vector>
  5.  
  6.  
  7. using namespace std;
  8.  
  9. //НОД(а,б)
  10. int gcd(int a, int b)
  11. {
  12.     while (b)
  13.  
  14.     {
  15.         int temp = b;
  16.         b = a % b;
  17.         a = temp;
  18.     }
  19.  
  20.     return a;
  21. }
  22. // Запись из файла в строку
  23. string write_text_to_string()
  24. {
  25.     ifstream text_file;
  26.  
  27.     text_file.open("Зашифрованный текст.txt", ios::in);
  28.  
  29.     string text, temp;
  30.     text.clear();
  31.     temp.clear();
  32.  
  33.  
  34.     while (text_file)
  35.     {
  36.         text_file >> temp;
  37.         text += temp;
  38.         temp.clear();
  39.     }
  40.  
  41.     text_file.close();
  42.    
  43.     return(text);
  44. }
  45. // Поиск n-грамам
  46. void search_for_reps(string &text, int N, int min_repeat_count, int count_text_char)
  47. {
  48.     vector<string> N_gram;
  49.     vector<int> repetitions;
  50.  
  51.     string substring_1, substring_2;
  52.     substring_1.clear(), substring_2.clear();
  53.  
  54.     unsigned int repeat_count(0);
  55.  
  56.     for (unsigned int i = 0; (i < text.size() - N) || (i < count_text_char); i++)
  57.     {
  58.         substring_1 = text.substr(i, N);
  59.  
  60.         if (N_gram.size() != 0)
  61.             for (unsigned int k = 0; k < N_gram.size(); k++)
  62.                 if (substring_1 == N_gram[k])
  63.                 {
  64.                     substring_1.clear();
  65.                     substring_1 = text.substr(i++, N);
  66.                 }
  67.  
  68.  
  69.         for (unsigned int j = 0; j < text.size() - N; j++)
  70.         {
  71.             substring_2 = text.substr(j, N);
  72.  
  73.             if (substring_1 == substring_2)
  74.                 repeat_count++;
  75.  
  76.             substring_2.clear();
  77.         }
  78.  
  79.         if (repeat_count > min_repeat_count)
  80.         {
  81.             N_gram.push_back(substring_1);
  82.             repetitions.push_back(repeat_count);
  83.             cout << substring_1 << "  " << repeat_count << endl << endl;
  84.         }
  85.         substring_1.clear();
  86.         repeat_count = 0;
  87.  
  88.     }
  89. }
  90. // Индексы вхождения  n-грамам
  91. vector<int> index_entries(string &mask, string &text)
  92. {
  93.     //cout<<"\n" << mask << " Входит в текст в позициях:\n ";
  94.  
  95.     vector<int> index_number;
  96.     index_number.clear();
  97.  
  98.  
  99.     for (unsigned int i = 0; i < text.size() - mask.size(); i++)
  100.  
  101.         if (mask == text.substr(i, mask.size()))
  102.         {
  103.             index_number.push_back(i);
  104.             //cout << i << " \n";
  105.         }
  106.    
  107.  
  108.     return (index_number);
  109. }
  110. // Расчет дистанций между двумя n-грамами
  111. vector<int> dist(string &mask, string &text)
  112. {
  113.     vector<int>index_number = index_entries(mask, text);
  114.     vector<int> dist(index_number.size() - 1);
  115.  
  116.     for (unsigned int i = 0; i < dist.size(); i++)
  117.     {
  118.         dist[i] = index_number[i + 1] - index_number[i];
  119.     }
  120.     return(dist);
  121. }
  122. // НОД дистанций между двумя n-грамами
  123. int gcd_dist(vector<int> &dist)
  124. {
  125.     int D=dist[0];
  126.     for (unsigned int i = 1; i < dist.size(); i++)
  127.     {
  128.         D = gcd(dist[i],D);
  129.     }
  130.  
  131.     return(D);
  132. }
  133. // Частотный анализ текста
  134. void frequency_of_text_analysis(string &text)
  135. {
  136.     string alphabet = "АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЫЬЭЮЯ_";
  137.  
  138.     ofstream fout("Подсчет количества каждого символа алфавита в текте.txt");
  139.  
  140.     for (unsigned int i = 0; i < alphabet.size(); i++)
  141.     {
  142.         unsigned int counter = 0;
  143.  
  144.         for (unsigned int j = 0; j < text.size(); j++)
  145.         {
  146.  
  147.             if (alphabet[i] == text[j])
  148.                 counter++;
  149.         }
  150.  
  151.  
  152.         fout << alphabet[i] << ": " << counter << endl;
  153.     }
  154.  
  155.     fout.close();
  156. }
  157. //Вычисление дистанции между двумя n-грамами, с учетом возможного размера ключа
  158. int gcd_dist_2(vector<int> &dist)
  159. {
  160.     ofstream fout("Длина ключа.txt", ios_base::app);
  161.  
  162.     fout << endl;
  163.     fout << "По заданию длина ключа равна d, где 5 <=d<=12:\n";
  164.  
  165.     for (unsigned int i = 0; i < dist.size(); i++)
  166.         for (unsigned int j = 1; j < dist.size()-i; j++)
  167.         {
  168.             if( (gcd(dist[i], dist[j + i])>4)&&(gcd(dist[i], dist[j + i])<13))
  169.             fout << "НОД(" << dist[i] << ", " << dist[i + j] << ") = " << gcd(dist[i], dist[j + i])<< endl;
  170.         }
  171.  
  172.     fout.close();
  173.     return(0);
  174. }
  175. //Вычисление дистанции между двумя n-грамами, без учета возможного размера ключа
  176. int gcd_dist_1(vector<int> &dist, string &mask)
  177. {
  178.     ofstream fout("Длина ключа.txt", ios_base::app);
  179.  
  180.     fout << endl;
  181.     fout << "Исследуем расстояния между сочетаниями '"<<mask<<"'. Какие-то совпадения могут оказаться случайными, а какие-то содержат информацию\nо длине ключа. Вычислим НОД (попарно):\n";
  182.  
  183.     for (unsigned int i = 0; i < dist.size(); i++)
  184.         for (unsigned int j = 1; j < dist.size() - i; j++)
  185.             fout << "НОД(" << dist[i] << ", " << dist[i + j] << ") = " << gcd(dist[i], dist[j + i]) << endl;
  186.     fout.close();
  187.     return(0);
  188. }
  189. //Счетчик букв
  190. void letter_counter(string &alphabet, string &text)
  191. {
  192.     ofstream fout("Частотный анализ текста записаннаго по столбцам.txt", ios_base::app);
  193.  
  194.     for (unsigned int i = 0; i < alphabet.size(); i++)
  195.     {
  196.         unsigned int counter = 0;
  197.  
  198.         for (unsigned int j = 0; j < text.size(); j++)
  199.         {
  200.  
  201.             if (alphabet[i] == text[j])
  202.                 counter++;
  203.         }
  204.  
  205.         fout << "\n";
  206.  
  207.         fout << alphabet[i] << ": " << counter << "; \n";
  208.     }
  209.     fout.close();
  210.     return;
  211. }
  212.  
  213. // Частотный анализ текста разбитого по N столбцам, где N - длина ключа
  214. int frequency_analysis_on_the_columns(string &text, unsigned int n)
  215. {
  216.     vector<string> rows;
  217.  
  218.     while (text.size() > 0)
  219.     {
  220.         rows.push_back(text.substr(0, n));
  221.         text = text.substr(n, text.size());
  222.    
  223.     }
  224.  
  225.     vector<string> cols(n);
  226.  
  227.     for (unsigned int i = 0; i < n; i++)
  228.     {
  229.         for (unsigned int j = 0; j < rows.size(); j++)
  230.         {
  231.             cols[i] += rows[j].at(i);
  232.         }
  233.     }
  234.  
  235.     string alphabet = "АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЫЬЭЮЯ_";
  236.  
  237.     ofstream fout("Частотный анализ текста записаннаго по столбцам.txt", ios_base::app);
  238.  
  239.  
  240.     for (unsigned int i = 0; i < cols.size(); i++)
  241.     {
  242.         letter_counter(alphabet, cols[i]);
  243.  
  244.         fout << "Для столбца " << i + 1 << "\n____________________________________________________________________________________";
  245.  
  246.         fout << endl;
  247.     }
  248.     fout.close();
  249.     return 0;
  250. }
  251. //Расшифровка текста
  252. string decoding(string &text, string &key)
  253. {
  254.     string alphabet = "АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЫЬЭЮЯ_";
  255.  
  256.     vector<string> Vigenere_square(31);
  257.  
  258.     int row_table, column_table;
  259.     string  new_text;
  260.     char decoded_symbol;
  261.  
  262.     new_text.resize(text.size());
  263.  
  264.     for (int i = 0; i < 31; i++)
  265.         for (int j = 0; j < 31; j++)
  266.         {
  267.             Vigenere_square[i].resize(31);
  268.             Vigenere_square[i][j] = alphabet[(i + j)%31];
  269.         }
  270.  
  271.  
  272.     for(int i=0;i<key.size();i++)
  273.         for(int j = i; j<text.size()-5;j=j+key.size())
  274.         {
  275.             row_table = alphabet.find(key[i]);
  276.             column_table = Vigenere_square[row_table].find(text[j]);
  277.             decoded_symbol = alphabet[column_table];
  278.             new_text[j] = decoded_symbol;
  279.         }
  280.  
  281.     ofstream fout("Расшифрованный текст.txt");
  282.     fout << new_text;
  283.     fout.close();
  284.  
  285.  
  286.     // Вывод квадрата Вижинера в кнсоль
  287.     for (int i = 0; i < 31; i++)
  288.         for (int j = 0; j < 31; j++)
  289.         {
  290.             cout<< Vigenere_square[i][j]<< " ";
  291.             if (j == 30) cout << "\n";
  292.         }
  293.     return  new_text;
  294. }
  295.  
  296. void main()
  297. {
  298.     setlocale(LC_ALL, "RUS");
  299.  
  300.     string text = write_text_to_string();
  301.     cout << text.size() << endl;
  302.  
  303.    
  304.     while (text.size() % 9 != 0) // Дополненение текста символами, не входящими в алфавит, до размера кратного размеру ключа
  305.     {                               //(Необходимо для коректной работы подпрограмм в которых происходит разбиение на строки)
  306.         text = text + '!';
  307.     }
  308.  
  309.     //search_for_reps(text, 4, 14, 1000);// Ищем сочитания по 4 символа, которые встречаются минимум 14 раз, расматриваем первую 1000 символов (сочетание должно встретится хотя бы раз)
  310.  
  311.     vector<int> a, b, c;
  312.     a = dist(string("ЗИЖ_"), text);
  313.     b = dist(string("ЯГЫЗ"), text);
  314.     c = dist(string("НГРД"), text);
  315.  
  316.     ofstream fout("Длина ключа.txt");
  317.  
  318.     //fout << "НОД расстояний группы 'ЗИЖ_' равен " << gcd_dist(a) << ". Делаем вывод, что период кратен " << gcd_dist(a) << "." << endl;
  319.     //fout << "НОД расстояний группы 'ЯГЫЗ' равен " << gcd_dist(b) << ". Делаем вывод, что период кратен " << gcd_dist(b) << "." << endl;
  320.     //fout << "НОД расстояний группы 'ЯГЫЗ' равен " << gcd_dist(c) << ". Делаем вывод, что период кратен " << gcd_dist(c) << "." << endl;
  321.     //fout << "Вероятней всего кодовое слово состоит из " << gcd(gcd(gcd_dist(a), gcd_dist(b)), gcd_dist(c)) << "символов." << endl;
  322.  
  323.     //fout << "\n"<<endl;
  324.  
  325.     gcd_dist_1(a, string("ЗИЖ_"));   gcd_dist_2(a);
  326.     gcd_dist_1(b, string("ЯГЫЗ"));  gcd_dist_2(b);
  327.     gcd_dist_1(c, string("НГРД"));  gcd_dist_2(c);
  328.    
  329.  
  330.     fout.close();
  331.  
  332.     frequency_analysis_on_the_columns(text, 9); // 9 - длина ключа
  333.  
  334.     frequency_of_text_analysis(text);
  335.  
  336.     decoding (text, string("ЗАВЕЩАНИЕ"));
  337.  
  338.     system("pause");
  339. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement