Шифр Цезаря, также известный как шифр сдвига, код Цезаря или сдвиг Цезаря — один из самых простых и наиболее широко известных методов шифрования.
Шифр Цезаря — это вид шифра подстановки, в котором каждый символ в открытом тексте заменяется символом, находящимся на некотором постоянном числе позиций левее или правее него в алфавите.
Например, в шифре со сдвигом вправо на 3, А была бы заменена на Г, Б станет Д, и так далее.
Шифр назван в честь римского полководца Гая Юлия Цезаря, использовавшего его для секретной переписки со своими генералами.
Шаг шифрования, выполняемый шифром Цезаря, часто включается как часть более сложных схем, таких как шифр Виженера, и всё ещё имеет современное приложение в системе ROT13. Как и все моноалфавитные шифры, шифр Цезаря легко взламывается и не имеет почти никакого применения на практике.
Программа просит ввести строку и ключ (размер сдвига). Если ключ k положителен, выполняется шифрование, если отрицателен — дешифрование.
Шифр Цезаря
program caesar1; const sym = ‘abcdefghijklmnopqrstuvwxyz ‘+ ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’+ ‘01234567890.’; var s0,s1: string; key:integer; procedure Encrypt(s: string;k: integer;var es:string); var l,ll,i,p: integer; c:char; begin l:=length(s); ll:=length(sym); es:=s; for i:=1 to l do begin c:=s[i]; p:=pos(c,sym); p:=p+k; if p>ll then p:=p-ll; es[i]:=sym[p]; end; end; procedure Decrypt(s:string;k:integer;var ds:string); var l,ll,i,p:integer; c: char; begin L:=length(s); ll:=length(sym); k:=1; ds:=s; for i:=1 to l do begin c:=s[i]; p:=pos(c,sym)-k; if p0 then Encrypt(s0,key,s1) else Decrypt(s0,-key,s1); writeln(s1); readln; end.
В программе шифруется текст «A simple example.» . Ключ генерируются случайным образом
from string import printable import random EXAMPLE_KEY = ».join(sorted(printable, key=lambda _:random.random())) def encode(plaintext, key): return ».join(key[printable.index(char)] for char in plaintext) def decode(plaintext, key): return ».join(printable[key.index(char)] for char in plaintext) original = «A simple example.» encoded = encode(original, EXAMPLE_KEY) decoded = decode(encoded, EXAMPLE_KEY) print(«»»The original is: <> Encoding it with the key: <> Gives: <> Decoding it by the same key gives: <>»»».format( original, EXAMPLE_KEY, encoded, decoded))
Похожие записи/страницы:
- Шифр Цезаря. Этот метод основан на замене каждой буквы шифруемого текста на другую путем смещения в алфавите от исходной…
- Дан текст из 200 символов. Зашифровать этот текст кодом Цезаря (каждый символ заменяется другим символом, код которого…
- Шифр замены (код Цезаря) Занумеровать алфавит исходного сообщения. Пусть m -длина алфавита сообщения; n,k — целые числа…
- Дан текст из 200 символов. Зашифровать этот текст кодом Цезаря (каждый символ заменяется другим символом, код которого…
- Имеются данные о семи линиях электропередач (ЛЭП): шифр, напряжение, протяженность, год ввода в действие, дата последних…
- Лозунговый шифр — Python(Питон)
- Реализация алгоритма шифрования Гаммирование — Python (Питон)
- Для записи текста использованы большие и малые латинские буквы, цифры и разделители. Заменить каждую букву новым…
Источник: retrolib.ru
Мастер-класс Шифр Цезаря
Реализация и взлом шифра Цезаря
Доброго времени суток, дорогие читатели и посетители! Сегодня небольшое погружение в мир криптографии и шифрования. Для меня эта область представляет некоторый интерес. А в целом, знать об этом нужно! В нашем цифровом веке без шифрования все уже давно бы рухнуло, ваша почта шифруется, ваши фото шифруются(в России вряд ли, но все же), ваши переписки тоже шифруются.
В идеальном интернете шифроваться должно вообще все, особенно любая финансовая информация. Финансы защищены даже лучше, чем личная жизнь. В любом случае, сегодня полезно хотя бы примерно знать, как это все работает. Для начала, предлагаю посмотреть на мою реализацию самого простого из шифров. А там и до RSA доберемся, поехали!
Прежде чем продолжить чтение, обратите внимание на реализации других шифров
- Реализация и взлом шифра Цезаря;
- Реализация и взлом шифра простой перестановки;
- Реализация и взлом шифра гаммирования;
- Реализация и взлом шифра простой замены.
Шифр простого сдвига
Так же известен под названием «Шифр Цезаря». Это шифр простой подстановки, при шифровании каждый символ текста заменяется символом, находящимся на некотором постоянном расстоянии левее или правее в алфавите. Наглядно на картинке из вики:
Обратная процедура расшифровки выполняется аналогично.
Со взломом уже поинтереснее. Я реализовал частотный анализ для взлома шифра цезаря. В двух словах суть можно описать следующим образом. Необходимо сравнить частоты появления символов в шифре с эталонными. И на основе этого сделать вывод, в какую сторону был смещен алфавит.
Я собираю все возможные сдвиги и беру в качестве результирующего самый часто встречающийся. Мой взлом отгадывает сдвиг почти со 100% вероятностью при достаточно больших текстах. Кстати, для тестов брал текст из библии вот здесь . По теории больше сказать нечего, сразу перейдем к реализации.
Реализация простого шифра сдвига на C++
C++ был выбран в качестве языка программирования по привычке. Во время написания программы, я понял, что проще было бы использовать интерпретируемый язык, например, Python. Но не бросать же дело на полпути?
Консольная программа, на вход принимает два файла, с открытым текстом и файл для шифра. Простенький интерфейс, код которого приведу в самом конце, спросит у нас нужное действие и вызовет соответствующую процедуру.
Используемые библиотеки
#include #include #include #include
Теперь к самому алгоритму.
Функция шифрования
Текст шифруется с помощью сдвигов по ascii таблице, отдельно обрабатываются случаи выхода за пределы таблицы. Пробелы и прочие символы пропускаются. Проверка на такой символ осуществляется с помощью функции bool checkChar(char c) .
На вход: имя файла с открытым текстом, имя файла для шифра, значение смещения.
На выходе: ничего.
bool checkChar(char c) < if(c == ‘ ‘ || c == ‘.’ || c == ‘,’ || c == ‘!’ || c == ‘?’ || c == ‘:’ || c == ‘;’) < return true; >else < return false; >> void encrypt(string inFileName, string outFileName, int offset) < ifstream inFile(inFileName.c_str()); //Считываем текст vectortext; while(true) < string str; inFile >> str; if(inFile.eof()) < break; >text.push_back(str); > inFile.close(); //Шифрование vector code; for(unsigned int i = 0; i < text.size(); i++) < string codeStr; for(unsigned int j = 0; j < text[i].length(); j++) < if(checkChar(text[i][j])) < codeStr.push_back(text[i][j]); >else < unsigned char symb = text[i][j] + offset; //Если вылезли за таблицу if(symb >’z’) < symb = ‘a’ + (symb — ‘z’) — 1; codeStr.push_back(symb); >else if(symb < ‘a’) < symb = ‘z’ — (‘a’ — symb) + 1; codeStr.push_back(symb); >else < codeStr.push_back(symb); >> > code.push_back(codeStr); > //Записываем в файл ofstream outFile(outFileName.c_str()); for(unsigned int i = 0; i < code.size(); i++) < outFile outFile.close(); return; >
Функция расшифровки
Шифр очень простой, поэтому расшифровка работает аналогично шифрованию. Символы сдвигаются обратно по алфавиту.
На вход: имя файла с шифром, имя файла для текста, значение смещения.
На выходе: ничего.
bool checkChar(char c) < if(c == ‘ ‘ || c == ‘.’ || c == ‘,’ || c == ‘!’ || c == ‘?’ || c == ‘:’ || c == ‘;’) < return true; >else < return false; >> void decrypt(string inFileName, string outFileName, int offset) < ifstream inFile(inFileName.c_str()); //Считываем код vectorcode; while(true) < string str; inFile >> str; if(inFile.eof()) < break; >code.push_back(str); > inFile.close(); //Дешифровка vector text; for(unsigned int i = 0; i < code.size(); i++) < string textStr; for(unsigned int j = 0; j < code[i].length(); j++) < if(checkChar(code[i][j])) < textStr.push_back(code[i][j]); >else < unsigned char symb = code[i][j] — offset; //Если вылезли за таблицу if(symb < ‘a’) < symb = ‘z’ — (‘a’ — symb) + 1; textStr.push_back(symb); >else if(symb > ‘z’) < symb = ‘a’ + (symb — ‘z’) — 1; textStr.push_back(symb); >else < textStr.push_back(symb); >> > text.push_back(textStr); > //Записываем в файл ofstream outFile(outFileName.c_str()); for(unsigned int i = 0; i < text.size(); i++) < outFile outFile.close(); return; >
Функция взлома
Добрались до интересного. Скажу сразу, чужих реализаций я не смотрел, писал по наитию, опираясь на статью из википедии. Получился неплохой результат. Как я уже говорил, в большинстве случаев, при большой длине текста, мой алгоритм угадывает смещение. Очень слабое место это переменная deff , которая отвечает за интервал, в который нужно попасть символу.
И функция получилась очень уж громоздкой, у меня есть подозрения, что на Питоне можно было написать покороче. Но, в любом случае, она работает.
На вход: имя файла с шифром, имя файла для текста.
На выходе: ничего, программа определяет смещение(с которым был зашифрован текст) и совершает дешифровку.
#define ALPH_SIZE 26 void initFreq(vector > /*источник: http://enghelp.ru/the_alphabet/687-chastota-vstrechaemosti-bukv.html */ F.push_back(make_pair(‘a’, 8.17)); F.push_back(make_pair(‘b’, 1.49)); F.push_back(make_pair(‘c’, 2.78)); F.push_back(make_pair(‘d’, 4.25)); F.push_back(make_pair(‘e’, 12.70)); F.push_back(make_pair(‘f’, 2.23)); F.push_back(make_pair(‘g’, 2.02)); F.push_back(make_pair(‘h’, 6.09)); F.push_back(make_pair(‘i’, 6.97)); F.push_back(make_pair(‘j’, 0.15)); F.push_back(make_pair(‘k’, 0.77)); F.push_back(make_pair(‘l’, 4.03)); F.push_back(make_pair(‘m’, 2.41)); F.push_back(make_pair(‘n’, 6.75)); F.push_back(make_pair(‘o’, 7.51)); F.push_back(make_pair(‘p’, 1.93)); F.push_back(make_pair(‘q’, 0.10)); F.push_back(make_pair(‘r’, 5.99)); F.push_back(make_pair(‘s’, 6.33)); F.push_back(make_pair(‘t’, 9.06)); F.push_back(make_pair(‘u’, 2.76)); F.push_back(make_pair(‘v’, 0.98)); F.push_back(make_pair(‘w’, 2.36)); F.push_back(make_pair(‘x’, 0.15)); F.push_back(make_pair(‘y’, 1.97)); F.push_back(make_pair(‘z’, 0.07)); return; >void hack(string inFileName, string outFileName) < vector> standFreq; initFreq(standFreq); vector > currentFreq(ALPH_SIZE); char symb = ‘a’; for(unsigned int i = 0; i < ALPH_SIZE; i++) < currentFreq[i].first = symb; currentFreq[i].second = 0.0; symb++; >ifstream inFile(inFileName.c_str()); //Считываем код vector code; while(true) < string str; inFile >> str; if(inFile.eof()) < break; >code.push_back(str); > inFile.close(); //Посчитать частоту символов //Всего символов int symbCount = 0; for(unsigned int i = 0; i < code.size(); i++) < for(unsigned int j = 0; j < code[i].length(); j++) < if(checkChar(code[i][j])) < continue; >else < symbCount++; for(unsigned int k = 0; k < ALPH_SIZE; k++) < if(code[i][j] == currentFreq[k].first) < //Одновременно считать количество символов в тексте currentFreq[k].second += 1.0; break; >> > > > //Текущая частота каждого for(unsigned int i = 0; i < ALPH_SIZE; i++) < currentFreq[i].second = (currentFreq[i].second / symbCount) * 100.0; >//Сравнить со стандартной частотой double deff = 0.25; //Допустимое отклонение vector slides; for(unsigned int i = 0; i < ALPH_SIZE; i++) < for(unsigned int j = 0; j < ALPH_SIZE; j++) < if(currentFreq[i].second >= (standFreq[j].second — deff) currentFreq[i].second > > //Выбираем смещение sort(slides.begin(), slides.end()); int count = 0; int maxCount = count; int slide = 0; for(unsigned int i = 1; i < slides.size(); i++) < if(slides[i-1] == slides[i]) < count++; >else < if(count >maxCount) < maxCount = count; slide = slides[i-1]; >count = 0; > > cout << «slide = » << slide << endl; //Дешифровать с использованием найденного смещения vectortext; for(unsigned int i = 0; i < code.size(); i++) < string textStr; for(unsigned int j = 0; j < code[i].length(); j++) < if(checkChar(code[i][j])) < textStr.push_back(code[i][j]); >else < unsigned char symb = code[i][j] — slide; //Если вылезли за таблицу if(symb < ‘a’) < symb = ‘z’ — (‘a’ — symb) + 1; textStr.push_back(symb); >else if(symb > ‘z’) < symb = ‘a’ + (symb — ‘z’) — 1; textStr.push_back(symb); >else < textStr.push_back(symb); >> > text.push_back(textStr); > //Записываем в файл ofstream outFile(outFileName.c_str()); for(unsigned int i = 0; i < text.size(); i++) < outFile outFile.close(); return; >
Интерфейс программы
Консольный. Команд всего четыре: encrypt, decrypt, hack, exit. Из названия легко угадывается действие. Интерфейс выглядит вот так:
int main() < while(true) < cout > action; if(action == «encrypt») < cout > inFileName; cout > outFileName; cout > offset; encrypt(inFileName, outFileName, offset); > else if(action == «decrypt») < cout > inFileName; cout > outFileName; cout > offset; decrypt(inFileName, outFileName, offset); > else if(action == «hack») < cout > inFileName; cout > outFileName; hack(inFileName, outFileName); > else if(action == «exit») < break; >else < cout > return 0; >
Заключение
В заключении можно сказать, что это только начало. Я буду реализовывать и другие аогоритмы шифрования.
От простых к более сложным. Возможно, однажды, я перейду на Python вместо C++. Интерпретируемый язык для шифрования подходит больше. На этом все, спасибо за внимание!
Источник: mindhalls.ru
«Шифр Цезаря (Код Цезаря) — пример на С# » Visual Studio
Разработать программу, кодирующую входную строку методом моноалфавитной подстановки, используя «шифр Цезаря». Программа должна поддерживать ввод широких символов (UNICODE).
Допустимые символы – ВСЕ. т.е. все символы английского (латинского) и русского алфавитов, цифры и другие знаки вводимые с клавиатуры
Данные на входе и интерфейс программы на C# Visual Studio
Программа должна закодировать входную строку методом моноалфавитной подстановки, используя шифр Цезаря. К цифровому коду каждой буквы (или другого символа) прибавить заданное пользователем значение key (ключ). Если получившийся код выходит за пределы указанных наборов символов, то считать, что за последним символом набора снова следует первый (цикл по кольцу). Вывод результата кодирования-декодирования представить на этой же форме.
Возможности калькулятора по шифрованию и дешифрованию
видео смотреть/скачать
Если не удалось запустить видео, воспользуйтесь этой ссылкой . видео на VK.com
Или этой ссылкой . видео на YouTube
Рис.1 Данные на входе и интерфейс программы Шифр Код Цезаря на С#
Перебор символов строки в цикле
for(int i=0;i
<
foreach (Clent v in this)
<
tmp = v.Repl(m.Substring(i, 1), key);
if (tmp != «») //нужная лента найдена, замена символу определена
<
res += tmp;
break; // прерывается foreach (перебор лент)
>
>
if (tmp == «») res += m.Substring(i, 1); //незнакомый символ оставляю без изменений
>
Тестирование готового приложения Шифр Цезаря
Решение:
Код очень короткий:
файл Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CezarCS
<
public partial class Form1 : Form
<
Cezar Me = new Cezar();
Тестирование — это наиболее важный этап в жизненном цикле программного продукта. Поэтому не верьте картинкам, фильмам и сказкам…
Только личное тестирование во всех наиболее сложных сочетаниях данных — должно убедить Вас в доброкачественности алгоритма и исходного кода!
Классы, упрощающие решение задачи
Всего два класса: Clent — лента Цезаря и собственно Cezar, обеспечивающий своим методом Codeс и кодирование, и декодирование…
Почему я назвал первый класс «лентой»? У лент в нашей обычной жизни нет проблем с длиной. Какой длины лента нужна, такой и отстригай от большого мотка… И вторая особенность лент: ее легко закольцевать, т.е. соединить (сшить, склеить) два ее конца.
Посмотрите на конструктор… он принимает строку любой длины…
Метод Repl(замена) по параметрам «символ»(m) и «смещение»(key) вернет новый символ в закольцованной ленте.
class Clent
<
string le;
Как видим, если символ принадлежит набору ленты, то возвращается новый символ этого набора в зависимости от величины смещения (отрицательного или положительного – не важно). Набор как бы закольцован (за пределы набора выйти нельзя). Функция возвращает пустую строку если символ не принадлежит набору.
Использование классов показано в программе…
Если у Вас остались вопросы, то задать их Вы можете, нажав на эту кнопочку .
Поделиться в соц сетях:
Источник: orenstudent.ru