StoneHaos

cezar

Dec 5th, 2019
167
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <clocale>
  4. #include <string>
  5. #include <cctype>
  6. #include <vector>
  7. #include <string>
  8. #include <cstring>
  9. using namespace std;
  10.  
  11. typedef unsigned short int usi;
  12. typedef unsigned char uc;
  13.  
  14. // Функция возвращает код русского символа (в таблице Юникода) записанного в utf-8
  15. usi getcode(usi c) {
  16.     usi ret = 0, p1 = 0xff00, p2 = 0x00ff;
  17.     uc a = 0x1f, b = 0x3f;
  18.     ret += (((c & p1) >> 8) & a);
  19.     ret <<= 6;
  20.     ret += (c & p2 & b);
  21.     return ret;
  22. }
  23.  
  24. // Функция возвращает преобразованный в utf-8 код русского символа
  25. usi toutf8(usi c) {
  26.     usi ret = 0;
  27.     uc a = 0xc0, b = 0x80;
  28.     b += c & 0x003f;
  29.     c >>= 6;
  30.     a += c & 0x001f;
  31.     ret += a;
  32.     ret <<= 8;
  33.     ret += b;
  34.     return ret;
  35. }
  36.  
  37. bool isupper_ru(usi c) {
  38.     return c == 0x401 || c >= 0x410 && c <= 0x42f;
  39. }
  40.  
  41. void crypto(string &s, int offset) {
  42.     if (offset < 0)
  43.         offset = 33 + offset;
  44.     unsigned short int a = 0;
  45.     unsigned char b = 0x80;
  46.     for (int i = 0; i < s.size(); ++ i) {
  47.         if (s[i] < 0) {
  48.             usi t = 0, code;
  49.             // Получение кода utf-8
  50.             t += (uc)s[i];
  51.             t <<= 8;
  52.             t += (uc)s[i + 1];
  53.             //
  54.             code = getcode(t);
  55.             /*
  56.                 (Ниже) Сдвиг русского символа по шифру Цезаря
  57.                 по определённому смещению.
  58.                 Отдельное описание для строчных и заглавных букв.
  59.                 Код символа для удобства преобразуется
  60.                 в порядковый номер буквы в алфавите и в этом виде
  61.                 происходит сдвиг.
  62.             */
  63.             if (isupper_ru(code)) {
  64.                 code -= 0x410;
  65.                 if (code >= 6) // Выделяется место для буквы Ё
  66.                     ++ code;   //
  67.                 if (code < 0)     // Буква Ё ставится на 6-ую позицию (начиная с 0)
  68.                     code = 6;     //
  69.                 code = (code + offset) % 33;
  70.                 if (code == 6)   //
  71.                     code = -15;  // Обратная трансформация русского символа.
  72.                 if (code >= 7)   // Для Ё выбирается значение в соответсвии
  73.                     -- code;     // с таблицей Юникода.
  74.                 code += 0x410;
  75.             }
  76.             else {
  77.                 code -= 0x430;
  78.                 if (code >= 6 && code <= 32)
  79.                     ++ code;
  80.                 if (code > 32)
  81.                     code = 6;
  82.                 code = (code + offset) % 33;
  83.                 if (code == 6)
  84.                     code = 33;
  85.                 if (code >= 7 && code != 33)
  86.                     -- code;
  87.                 code += 0x430;
  88.             }
  89.             code = toutf8(code);
  90.             s[i] = char(code >> 8);
  91.             s[i + 1] = char(code & 0x00ff);
  92.             ++ i;
  93.         }
  94.     }
  95. }
  96.  
  97. // Функция возвращает vector из n первых слов словаря данной программы
  98. vector<string> read_words(const int n) {
  99.     vector<string> ret(0);
  100.     char buf[128];
  101.     FILE* f = fopen("words.num", "r");
  102.     for (int i = 0; i < n; ++ i) {
  103.         fscanf(f, "%*s%*s%s", buf);
  104.         ret.push_back(string(buf));
  105.     }
  106.     fclose(f);
  107.     return ret;
  108. }
  109.  
  110. // Функция возвращает только русские слова из входного файла
  111. vector<string> read_message() {
  112.     vector<string> ret(0);
  113.     char buf[8192];
  114.     int last, current;
  115.     FILE* f = fopen("input.txt", "r");
  116.     while (fscanf(f, "%[А-ПР-Яа-пр-яЁё]%*[!-~\n ]", buf)) {
  117.         current = ftell(f);
  118.         if (current == last)
  119.             break;
  120.         last = current;
  121.         ret.push_back(string(buf));
  122.     }
  123.     fclose(f);
  124.     return ret;
  125. }
  126.  
  127. const int _n = 69307;
  128.  
  129. int main(void) {
  130.     //setlocale(LC_ALL, "Russian");
  131.     //69307
  132.     vector<string> words = read_words(_n),
  133.     message = read_message();
  134.    
  135.     return 0;
  136. }
RAW Paste Data