Шифр Цезаря на C# — это тип шифра подстановки, в котором каждый символ в открытом тексте должен заменяться символом, расположенным на определенном постоянном количестве позиций левее или правее него в алфавите.
Общие сведения о шифре Цезаря
Шифр Цезаря назван в честь Юлия Цезаря, который, как утверждает в своей работе «Жизнь двенадцати цезарей» Светоний, применял его со смещением на три символа для защиты военных сообщений. Следует отметить, что, хотя Цезарь стал первым известным человеком, применившим данную схему, иные шифры с подстановками, как известно, применялись и раньше.
Когда у Цезаря появлялась необходимость конфиденциальной передачи информации, он старался зашифровать сообщение, то есть так изменить очередность символов алфавита, чтобы невозможно было разобрать ни одно из слов. Если кто-либо пытался дешифровать его и узнать его смысл, то ему нужно было подставить вместо каждой буквы в послании четвертую за ней по счету букву алфавита, то есть, D, вместо A, и так далее. Нет информации, насколько эффективным являлся шифр Цезаря для своего времени, но, скорее всего, он был достаточно безопасным, учитывая тот факт, что почти все враги Цезаря были неграмотными.
Существуют приложения, предназначенные для шифрования текста, написанные на языке программирования Cи, которые используют метод сдвига символов, также известный как шифр Цезаря. Пользователю нужно ввести натуральное число n, определяющее количество символов, на которое следует сдвинуть текущий символ. К примеру, если n равняется двум, то буква «б» превратится в букву «г». При шифровании делается предположение, что буквы следуют по кругу, и это означает, что за буквой «я» будет следовать буква «а». Программа обязана уметь исполнять как шифрование, так и дешифровку текста. Шифровать можно русские и английские буквы, а другие символы, такие как, знаки препинания, пробелы и тому подобное, можно оставить их без изменения. Ввод и вывод информации обычно реализуется из файла.
Шифр Цезаря на C Sharp
Для того чтобы сформировать программу на Си, реализующую шифр Цезаря, следует сначала подключить нужные библиотеки и определить пару констант, а именно, количество букв в английском и русском алфавитах соответственно. Следует отметить, что константу RUS следует сделать равной 32, поскольку буква «е» в таблице символов ASCII в кодировке Wíndows 1251 расположена за границей русского алфавита. Ниже приведен текст этого фрагмента программы:
#ínclude ∠stdío.h>
#ínclude ∠locale>
#defíne ENG 26
#defíne RUS 32
Далее следует создать функцию, которая осуществит шифрование текста из входного файла. В качестве аргумента эта функция будет использовать число n, которое является количеством символов, на которое следует сдвинуть символы в тексте:
void encrypt (ínt n)
{
FILE fp1, fp2;
fopen_s(&fp1, "ínput.txt", "r");
fopen_s(&fp2, "output.txt", "w");
ínt flag;
char c;
c = getc(fp1);
whíle (!feof(fp1))
{
flag = 0; //обработан ли текущий символ
íf (c >= 'A' && c ∠= 'Z')
{ c = c + (n % ENG);
íf (c > 'Z') c = 'A' + (c - 'Z') - 1;
fpríntf (fp2, "%c", c);
flag = 1;
}
íf (c >= 'a' && c ∠= 'z')
{
c = c + (n % ENG);
íf (c > 'z') c = 'a' + (c - 'z') – 1 ; fpríntf (fp2, "%c", c);
flag = 1;
}
íf (c >= 'А' && c ∠= 'Я')
{
c = c + (n % RUS);
íf (c > 'Я') c = 'А' + (c - 'Я') - 1;
fpríntf (fp2, "%c", c);
flag = 1;
}
íf (c>='а' && c∠='я')
{
c = c + (n % RUS);
íf (c > 'я') c = 'а' + (c - 'я') - 1;
fpríntf (fp2, "%c", c);
flag = 1;
}
if (!flag) fpríntf (fp2, "%c", c);
c = getc(fp1);
}
fclose (fp1);
fclose (fp2);
}
В начале работы данной функции открывается входной файл «ínput.txt» для чтения, затем открывается (или если его нет, то он создается) выходной файл «output.txt», предназначенный для записи. При помощи функции getc() осуществляется считывание символов по одному из входного файла.
Далее выполняется запуск цикла с предусловием whíle (!feof(fp1)), функция в скобках осуществляет проверку достижения конца файла. В íf’ах реализуется проверка принадлежности поступившего символа к одной из групп символов, если считанный символ «c» является русской или английской буквой, то выполняется ее шифрование, а именно, реализуется сдвиг:
c = c + (n % ENG).
Остаток от деления на количество букв в алфавите следует использовать для того, чтобы при n >= ENG убирать лишний круг (или круги) прохода по алфавиту. Когда зашифрованная буква выходит за границы алфавита, то выполняется проход по кругу и возврат к началу:
if (c > ‘Z’) c = ‘A’ + (c — ‘Z’) — 1;.
После этого выполняется запись символа в выходной файл.
В случае, когда считанный символ «c» не является буквой, а является иным символом (для контроля этого служит переменная flag), то в таком случае должно выполниться условие if (!flag) fprintf (fp2, «%c», c); и нужно записать символ «c» в выходной файл без каких-либо изменений. В конце работы функции закрываются файлы «input.txt» и «output.txt».
Далее формируется функция, которая способна расшифровать текст. Работает функция практически аналогично предыдущей, за исключение того, что в этом варианте символы не прибавляются, а вычитаются:
voíd decípher (ínt n)
{
FILE fp1, fp2;
fopen_s(&fp1, "ínput.txt", "r");
fopen_s(&fp2, "output.txt", "w");
ínt flag;
char c;
c = getc(fp1);
whíle (!feof(fp1))
{
flag = 0;
íf (c >= 'A' && c ∠= 'Z')
{
c = c - (n % ENG);
íf (c ∠ 'A') c = 'Z' - ('A' - c) + 1;
fpríntf (fp2, "%c", c);
flag = 1;
}
if (c >= 'a' && c ∠= 'z')
{
c = c - (n % ENG);
if (c ∠ 'a') c = 'z' - ('a' - c) + 1;
fpríntf (fp2, "%c", c);
flag = 1;
}
íf (c >= 'А' && c ∠= 'Я')
{
c = c - (n % RUS);
íf (c ∠ 'А') c = 'Я' - ('А' - c) + 1;
fpríntf (fp2, "%c", c);
flag = 1;
}
íf (c >= 'а' && c ∠= 'я')
{
c = c - (n % RUS);
íf (c ∠ 'а') c = 'я' - ('а' - c) + 1;
fpríntf (fp2, "%c", c);
flag = 1;
}
íf (!flag) fpríntf (fp2, "%c", c);
c = getc(fp1);
}
fclose (fp1);
fclose (fp2);
}
Далее формируется функция main:
ínt maín ()
{ setlocale(LC_ALL,"Russían");
ínt n;
príntf ("Ввод натурального n: ");
scanf_s ("%d", &n);
getchar (); //требуется для того, чтобы отследить символ клавиши ENTER, нажатой при вводе числа n
íf (n ∠ 1) return 0;
príntf ("Для зашифровки текста введите a, для расшифровки b: ");
char c;
scanf_s ("%c", &c, 1);
íf (c == 'a') encrypt (n);
íf (c == 'b') decípher (n);
return 0;
}