Крипто-форум crprogram.16mb.com

Програмування, Delphi, криптографія, криптоаналіз, шифри, вихідні коди, вирішення задач, приклади програм

Часовий пояс: UTC десь + 2 години




Розпочати нову тему Відповісти  [ 12 повідомлень ] 
Автор Повідомлення
 Заголовок повідомлення: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Як правло під час навчання у відповідних ВУЗах за відповідною( ) спеціальністю, доводиться вірішувати некладні задачі - як реалізація простої підстановки (заміни), перестановки, шифра Віженера для націоналіних алфавітів.

Отже, з чого почати?

Спочатку розглянемо шифри, які як правило, доводиться писати у навчальних цілях.

Нам не потрібна компактність програми, нам не потрібна швидкодія.

Нам потрібен:
- зрозумілий вихідний код.
- зручний інтерфейс.
- покроковий звіт виконання процесу шифрування.


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Отже почнемо з інтерфейсу.

Нам потрібні:

  • поле вводу відкритого тексту (edit memo)
  • поле виводу шифртексту (edit memo)
  • кнопка вибору режиму - шифрування/розшифрування ( button)
  • кнопка вибору ключа ( button)
  • кнопка генерації колюча ( button)
  • поле виводу проміжної інформації (edit memo)
  • поле відображення ключа (stringgrid)

Як бачимо, щоб вирішити найпростішу задачу, нам потрібна ціла низка об"єктів.

Звісно, можна було б закинути одну кнопку, і для неї написати мега-код, але це навчальна задача, і нам потрібно не навчитись програмувати прості шифри, а за допомогою програми наочно побачити як вони працюють, що ми отримуємо на виході, і щоб у нас була можливість поекспериментувати.


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Отже, закинемо на форму відповідні елементи:
Зображення


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Перед тим як рухатись далі деяке пояснення:

Реалізувати програмно простий шифр (того ж Цезаря) можна десятками різних способів.
І найкращого оптимального не існує, це справа смаку.

Але ми будемо використовувати одну з більш-менш оптимальних реалізацій, яка покликана в першу чергу забезпечити розуміння роботи шифру, зручність представлення наборів знаків, і в останню чергу швидкодію та красу програмної реалізації ( ці задачі ми теж будемо вирішувати, але в наступному розділі).

Я бачив чимало надзвичайно незручних реалізацій,
типові:
-використання власного набору алфавітів, і робота з літерами, наприклад:
Цитата:
for i:=1 to 20 do
if s[i]='A' then ....
if s[i]='B' then ....

-використання таблиці ASCII:

Цитата:
for i:=2 to 17 do
t[i]:=char((ord('A')-223)+3);


Як тільки у нас змінюється алфавіт, наприклад при переписуванні програми з російського алфавіту на український, нам доведеться переписати пів програми, без гарантії відсутності помилок. І переписувати і самі модулі шифрування...

Тому ми підемо старим, перевіреним роками, дідівським методом: (знову повторюсь - у програмах для навчальної мети!)
позначення букв алфавіту числами:
Код:
а-0
б-1
в-2

і т.д.

Ми не претендуємо на авторство цього методу, так як він був відомий ще з ХІХст.

У чому перевага, скажете ви?
Перевага у можливості роботи з числами, без прив'язки до конкретного алфавіту.
Чиста математика, яка буде справедлива і для білоруського, і для казахського алфавітів...
У тим самим у розумінні внутрішньої роботи шифру.

Недолік - в ускладенні вводу/виводу літер.


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Для російського алфавіту:

Для переведення з кодування ASCII у числа 0..L будемо використовувати функцію:
Код:
function CifraDeLetra(x:string):byte;  // Літеру в її номер в алфавіті
var
z:byte;
begin
//Російський алфавіт
//Пробіл, крапка, кома
z:=ord(x[1]);
case z of
32: CifraDeLetra:=32; //пробіл
45: CifraDeLetra:=33; //крапка
46: CifraDeLetra:=34; //кома
192..223: CifraDeLetra:=z-192; //А..Я
224..255: CifraDeLetra:=z-224; //а..я
else
CifraDeLetra:=32; //замінюємо на пробіл
end;
end;

і навпаки

Код:
function Caracter(x:byte):string; //по номеру в алфавіті друкуємо літеру
begin
//Російський алфавіт
//Пробіл, крапка, кома
case x of
32: Caracter:=' '; //пробіл
33: Caracter:='.'; //крапка
34: Caracter:=','; //кома
0..31: Caracter:=char(x+224); //а..я
end;

end;


Для українського алфавіту:

Код:
function CifraDeLetra(x:string):byte;  // Літеру в її номер в алфавіті
var
z:byte;
begin
//Український алфавіт
//Пробіл
z:=ord(x[1]);
case z of
224..227: CifraDeLetra:=z-224; //а..г
180: CifraDeLetra:=4; //ґ
228..229: CifraDeLetra:=z-223; //д..е
186: CifraDeLetra:=7; //є
230..232: CifraDeLetra:=z-222; //ж..и
179: CifraDeLetra:=11; //і
191: CifraDeLetra:=12; //ї
233..249: CifraDeLetra:=z-220; //й..щ
252: CifraDeLetra:=30; //ь
254..255: CifraDeLetra:=z-223; //ю..я
else
CifraDeLetra:=33;
end;

end;

function Caracter(x:byte):string; //по номеру в алфавіті друкуємо літеру
begin
//Український алфавіт
//Пробіл
case x of
0..3: Caracter:=char(x+224); //а..г
4: Caracter:='ґ'; //ґ
5..6: Caracter:=char(x+223); //д..е
7: Caracter:='є'; //є
8..10: Caracter:=char(x+222); //ж..и
11: Caracter:='і'; //і
12: Caracter:='ї'; //ї
13..29: Caracter:=char(x+220); //й..щ
30: Caracter:='ь'; //ь
31..32: Caracter:=char(x+223); //ю..я
33: Caracter:=' '; //пробіл
end;

end;


(увага: у цьому повідомленні задається алфавіт!)


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Процедура шифрування, для прикладу шифр Цезаря:
Код:
procedure CipherZ;
var
i,L:integer;
begin
L:=35;
for i:=1 to ntxt do
begin
Ctxt[i]:=(Ptxt[i]+3) mod L;
form1.memo3.Lines.add(inttostr(i)+') '+inttostr(Ptxt[i])+'['+Caracter(Ptxt[i])+'] => '+inttostr(Ctxt[i])+'['+Caracter(Ctxt[i])+']');
end;

for i:=0 to (L-1) do
begin
form1.stringgrid1.Cells[0,i+1]:=inttostr(i);
form1.stringgrid1.Cells[1,i+1]:=Caracter(i);
form1.stringgrid1.Cells[2,i+1]:=Caracter((i+3) mod L);
end;

end;


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Оголошення загальних змінних
Код:
var
  Form1: TForm1;
  Ctxt,Ptxt:array[0..1000] of byte;
  ntxt:integer;


Код для кнопки Button1 "Зашифрувати"
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
s,rez:string;
begin

s:=memo1.text;
ntxt:=length(s);
for i:=1 to ntxt do
Ptxt[i]:=CifraDeLetra(s[i]);

CipherZ;

rez:='';
for i:=1 to ntxt do
rez:=rez+Caracter(Ctxt[i]);

memo2.Text:=rez;

end;


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Готові реалізації шифрів можна буде знайти у розділі Класична криптографія / Классическая криптография.

Отримаємо результат:
Зображення

І в результаті ми бачимо:
яка літера на яку змінювалась, їх номер, і чому "а" замінено на "г".


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Код кнопка для розшифровки Button2 "Розшифрувати" аналогічний:

Код:
procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
s,rez:string;
begin
s:=memo1.text;
ntxt:=length(s);
for i:=1 to ntxt do
  Ctxt[i]:=CifraDeLetra(s[i]);

CipherR;

rez:='';
for i:=1 to ntxt do
  rez:=rez+Caracter(Ptxt[i]);

memo2.Text:=rez;

end;


Процедура розшифровки:
Код:
procedure CipherR;
var
i,L:integer;
begin
L:=35;
for i:=1 to ntxt do
  Ptxt[i]:=(Ctxt[i]-3) mod L;
end;

(код менший за рахунок того що проміжна інформація не відображається).

Перший раз розібратись важкувато, але інтерфейс будемо використовувати у всіх навчальних шифрах, і буде змінюватись тільки метод шифрування.


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Кому потрібен повний проект - напишіть - закину повний архів.


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Якщо швидкість програми не така вже й важлива ( а для навчальною мети таких випадків 99%) можна переписати функції для алфавітів через pos:

Код:
function CifraDeLetra(x:string;aa:byte):byte;  // Літеру в її номер в алфавіті
var
z,tm:byte;
begin
tm:=pos(x,alfav[aa]);
if tm=0 then tm:=1;
CifraDeLetra:=tm-1;
end;

function Caracter(x:byte;aa:byte):string; //по номеру в алфавіті друкуємо літеру
var
sros:string;
begin
sros:=alfav[aa];
Caracter:=sros[x+1];
end;


де
alfav:array[0..9] of string;

та задаємо відповідні алфавіти:
Код:
alfav[0]:='абвгґдеєжзиіїйклмнопрстуфхцчшщьюя';    //Український
alfav[1]:='абвгґдеєжзиіїйклмнопрстуфхцчшщьюя ';   //Український+пробіл
alfav[2]:='абвгґдеєжзиіїйклмнопрстуфхцчшщьюя ,.';  //Український+пробіл+,.
alfav[3]:='абвгдеёжзийклмнопрстуфхцчшщъыьэюя';     //Російський
alfav[4]:='абвгдеёжзийклмнопрстуфхцчшщъыьэюя ';     //Російський+пробіл
alfav[5]:='абвгдежзийклмнопрстуфхцчшщыьэюя';      //Російський(Без "Ё" та "Ъ")
alfav[6]:='абвгдеёжзійклмнопрстуўфхцчшыьэюя';     //Білоруський
alfav[7]:='абвгдеёжзійклмнопрстуўфхцчшыьэюя ';    //Білоруський+пробіл
alfav[8]:='abcdefghijklmnopqrstuvwxyz';          //Англійський
alfav[9]:='абвгдежзийклмнопрстуфхцчшщъьюя'     //Болгарський


Повернутися наверх
  
 
 Заголовок повідомлення: Re: Навчальні шифри, інтерфейс.
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Тоді напишемо програму для шифра Цезаря.


Повернутися наверх
  
 
Показати повідомлення за:  Сортувати по:  
Розпочати нову тему Відповісти  [ 12 повідомлень ] 

Часовий пояс: UTC десь + 2 години



cron
Роwеrеd bу рhрВB® аnd Hostinger web hosting