Transact
|
Transact
#include typedef struct { long values[40][40]; long total; } BIGRAMM; #include "etalon.h" BIGRAMM current; // использованный алфавит (укороченный в целях упрощения) // «а» маленькое играет роль пробела и заменителя всех остальных знаков unsigned char alpha[33] = {'А','Б','В','Г','Д','Е','Ж','З','И','Й','К','Л', 'М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь', 'Э','Ю','Я','а'}; // ключ-таблица для зашифрования unsigned char key[33] = {'Б','В','Г','Д','Е','Ж','З','И','Й','К','Л','М','Н', 'О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э', 'Ю','Я','а','А'}; // ключ-таблица для расшифрования unsigned char right_unkey[33] = {'Я','а','А','Б','В','Г','Д','Е','Ж','З','И', 'Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч', 'Ш','Щ', 'Ъ','Ы','Ь','Э','Ю'}; unsigned char unkey[33] = {'Е','П','Р','С','Т','Я','а','А','Б','В','Г','Д','Ж','З', 'И','Й','К','Л','М','Н','О','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ', 'Ы','Ь','Э','Ю'}; void encrypt(unsigned char *buf, int len, char *key) { for (int i = 0; i < len; i++) if (buf[i] >= 0xC0 && buf[i] <= 0xE0) buf[i] = key[buf[i]-0xC0]; } void decrypt(unsigned char *buf, int len, char *key) { for (int i = 0; i < len; i++) if (buf[i] >= 0xC0 && buf[i] <= 0xE0) buf[i] = unkey[buf[i]-0xC0]; } // вычисляем биграммы void calc_gramm(unsigned char *buf, int len) { for (int i = 0; i < len-1; i++) { current.values[ buf[i]-0xC0 ][ buf[i+1]-0xC0 ]++; current.total++; } } // вычисляем «расстояние» рабочего ключа до настоящего double calc_measure() { double result = 0; if (!current.total) current.total++; for (int i = 0; i < 40; i++) for (int j = 0; j < 40; j++) result += fabs(((double) current.values[i][j]/current.total) - ((double) etalon.values[i][j]/etalon.total)); return result; } // поиск ключа void findkey_jakobsen(char *buf, int len, char *guesskey) { char work_key[33]; double V, V_; int c, pos, sym; char *temp, s; temp = (char *) malloc(len); memcpy(work_key, guesskey, sizeof(work_key)); strncpy(temp, buf, len); memset(¤t, 0, sizeof(current)); calc_gramm(temp, len); V = calc_measure(); randomize(); c = 0; for (;;) { // переставляем символы в ключе pos = rand() % 33; sym = (pos + 1 + rand()) % 33; s = work_key[pos]; work_key[pos] = work_key[sym]; work_key[sym] = s; // дешифруем текст strncpy(temp, buf, len); decrypt(temp, len, work_key); memset(¤t, 0, sizeof(current)); calc_gramm(temp, len); // считаем расстояние до эталона V_ = calc_measure(); if (++c % 1000 == 0) printf("%f < %f, %d, %d\n", V_, V, pos, sym); if (V_ < V) { // ура! улучшили результат! printf("WORK_KEY == %s, KEY = %s (V == %f, V_ == %f)", work_key, guesskey, V, V_); printf("!!!\n", work_key); memcpy(guesskey, work_key, sizeof(work_key)); V = V_; } else // оставляем все без изменений memcpy(work_key, guesskey, sizeof(work_key)); } printf("%f", V); } #define MAKE_ETALON 0 int main(int argc, char* argv[]) { char text[] = "Каждое время года имеет свою особенность. Зимой всё покрывается белым снегом. Зима начинает год и заканчивает его. Весной снег тает, распускаются цветы, прилетают птицы, цветут сады. Летом созревают ягоды, грибы, овощи и фрукты. Это самая теплая пора года. Осенью природа засыпает. Опадают листья"; int len = strlen(text); for (int i = 0; i < len; i++) if (text[i] < 'А' || text[i] > 'Я') text[i] = 0xE0; if (MAKE_ETALON) { FILE *f = fopen("collect.txt", "rb"); char buf[32768]; while (!feof(f)) { int r = fread(buf, 1, sizeof(buf), f); for (int i = 0; i < r; i++) if (buf[i] < 'А' || buf[i] > 'Я') buf[i] = 0xE0; calc_gramm(buf, r); } fclose(f); f = fopen("etalon.h", "wt"); fprintf(f, "BIGRAMM etalon = {\n"); for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) fprintf(f, "%d ", current.values[i][j]); fprintf(f, "\n"); } fprintf(f, "%d };\n", current.total); fclose(f); return 0; } encrypt(text, len, key); printf("%s\n", text); findkey_jakobsen(text, len, unkey); decrypt(text, len, unkey);
return 0; } Download Do'stlaringiz bilan baham: |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling