Error C2664 - C (СИ)
Формулировка задачи:
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 (;;) { // переставляем символы в ключе
Решение задачи: «Error C2664»
textual
Листинг программы
#include "stdafx.h" #include "unidef.h" #include "math.h" #include "malloc.h" #include "iostream" //int _tmain(int argc, _TCHAR* argv[]) //{ // return 0; //} // биграммы typedef struct { long values[40][40]; long total; } BIGRAMM; #include "etalon.h" BIGRAMM current; // использованный алфавит (укороченный в целях упрощения) // «а» маленькое играет роль пробела и заменителя всех остальных знаков unsigned char alpha[34] = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯа"; //{'А','Б','В','Г','Д','Е','Ж','З','И','Й','К','Л', //'М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь', //'Э','Ю','Я','а'}; // ключ-таблица для зашифрования unsigned char key[34] = "БВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯаА"; //{'Б','В','Г','Д','Е','Ж','З','И','Й','К','Л','М','Н', //'О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э', //'Ю','Я','а','А'}; // ключ-таблица для расшифрования unsigned char right_unkey[34] = "ЯаАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ"; //{'Я','а','А','Б','В','Г','Д','Е','Ж','З','И', //'Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч', //'Ш','Щ', //'Ъ','Ы','Ь','Э','Ю'}; unsigned char unkey[34] = "ЕПРСТЯаАБВГДЖЗИЙКЛМНОУФХЦЧШЩЪЫЬЭЮ"; //{'Е','П','Р','С','Т','Я','а','А','Б','В','Г','Д','Ж','З', //'И','Й','К','Л','М','Н','О','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ', //'Ы','Ь','Э','Ю'}; // шифр простой замены 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++; } } // вычисляем «расстояние» рабочего ключа до настоящего char etalon; 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); printf("%s\n", text); return 0; }
Объяснение кода листинга программы
- Программа написана на языке C.
- Ошибка C2664 возникает в функции
findkey_jakobsen
из-за несовместимости типов данных. Вероятно, проблема связана с неправильным использованием функцииmemcpy
илиstrncpy
. - В программе используется шифр простой замены, который реализуется функциями
encrypt
иdecrypt
. - Биграммы вычисляются с помощью функции
calc_gramm
. - Функция
calc_measure
вычисляетрасстояние
рабочего ключа до эталонного. - Для поиска ключа используется функция
findkey_jakobsen
. - В функции
main
создается эталонный ключ с помощью файлаcollect.txt
и вычисляется его значение. - Затем текст шифруется с помощью найденного ключа и выводится на экран.
- После этого происходит поиск ключа с помощью функции
findkey_jakobsen
, и текст расшифровывается с помощью найденного ключа. - Расшифрованный текст выводится на экран.
- В конце программы возвращается значение 0, что означает успешное выполнение программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д