Лекции.Орг


Поиск:




Описание работы программы Vizhener.

Теоретическая часть.

Шифр Виженера (Chiffre de Vigenère) — метод полиалфавитного шифрования буквенного текста с использованием ключевого слова.

Этот метод является простой формой многоалфавитной замены. Шифр Виженера изобретался многократно. Впервые этот метод описал Джован Баттиста Беллазо (итал. Giovan Battista Bellaso) в книге La cifra del. Sig. Giovan Battista Bellasо в 1553 году, однако в XIX веке получил имя Блеза Виженера, французского дипломата. Метод прост для понимания и реализации, он является недоступным для простых методов криптоанализа.

В шифре Цезаря каждая буква алфавита сдвигается на несколько строк; например в шифре Цезаря при сдвиге +3, A стало бы D, B стало бы E и так далее. Шифр Виженера состоит из последовательности нескольких шифров Цезаря с различными значениями сдвига. Для зашифровывания может использоваться таблица алфавитов, называемая tabula recta или квадрат (таблица) Виженера. Применительно к латинскому алфавиту таблица Виженера составляется из строк по 26 символов, причём каждая следующая строка сдвигается на несколько позиций. Таким образом, в таблице получается 26 различных шифров Цезаря. На разных этапах кодировки шифр Виженера использует различные алфавиты из этой таблицы. На каждом этапе шифрования используются различные алфавиты, выбираемые в зависимости от символа ключевого слова. Например, предположим, что исходный текст имеет вид:

ATTACKATDAWN

Человек, посылающий сообщение, записывает ключевое слово («LEMON») циклически до тех пор, пока его длина не будет соответствовать длине исходного текста:

LEMONLEMONLE

Первый символ исходного текста A зашифрован последовательностью L, которая является первым символом ключа. Первый символ L шифрованного текста находится на пересечении строки L и столбца A в таблице Виженера. Точно так же для второго символа исходного текста используется второй символ ключа; то есть второй символ шифрованного текста X получается на пересечении строки E и столбца T. Остальная часть исходного текста шифруется подобным способом.

Исходный текст: ATTACKATDAWNКлюч: LEMONLEMONLEЗашифрованный текст: LXFOPVEFRNHR

Расшифровывание производится следующим образом: находим в таблице Виженера строку, соответствующую первому символу ключевого слова; в данной строке находим первый символ зашифрованного текста. Столбец, в котором находится данный символ, соответствует первому символу исходного текста. Следующие символы зашифрованного текста расшифровываются подобным образом.

Если буквы A-Z соответствуют числам 0-25, то шифрование Виженера можно записать в виде формулы:

Расшифровка:

 

Квадрат Виженера, или таблица Виженера, также известная как tabula recta, может быть использована для шифрования и расшифрования.

 

Описание работы программы Vizhener.

 

Программа выполняет функции шифрования и дешифрования текста по методу Виженера. В программе существует возможность извлекать и записывать текстовые данные из файлов с расширением.TXT, также в программе запрашивается пароль, без ввода которого не происходит расшифровки ранее зашифрованного программой файла (пароль также выполняет функции ключа в алгоритме шифрования). Существует возможность менять содержание алфавита прямо в интерфейсе программы, таблица Виженера возникает при нажатии на сочетание клавиш Ctrl+H.

 

 

Интерфейс программы:

 

Готовность к вводу данных или их загрузке:

 

Введенные данные для шифрования и пароль(активна кнопка «Зашифровать»):

 

Результат нажатия кнопки «Зашифровать»:

 

Введенные данные для дешифрования и пароль(активна кнопка «Расшифровать»):

 

Таблица Виженера с возможностью редактирования алфавита:

 

 

 

Листинг программы:

program Vizhener;

 

uses

Forms,

TablVin in 'TablVin.pas' {Form1};

 

{$R *.res}

 

begin

Application.Initialize;

Application.Title:= 'ВИЖЕНЕР';

Application.CreateForm(TForm1, Form1);

Application.Run;

end.

 

unit TablVin;

 

interface

 

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, Grids, ComCtrls, ExtCtrls, StdCtrls, Buttons, Menus;

 

type

TForm1 = class(TForm)

PC1: TPageControl;

TabSheet1: TTabSheet;

TabSheet2: TTabSheet;

SG1: TStringGrid;

Panel1: TPanel;

SB1: TSpeedButton;

SB2: TSpeedButton;

SG2: TStringGrid;

PopupMenu1: TPopupMenu;

N1: TMenuItem;

Edit1: TEdit;

Label1: TLabel;

REd1: TMemo;

REd2: TMemo;

SB3: TSpeedButton;

SB4: TSpeedButton;

SB5: TSpeedButton;

SB6: TSpeedButton;

SBar1: TStatusBar;

OD1: TOpenDialog;

SD1: TSaveDialog;

SB7: TSpeedButton;

MainMenu1: TMainMenu;

N2: TMenuItem;

N3: TMenuItem;

Timer1: TTimer;

SpeedButton1: TSpeedButton;

SpeedButton2: TSpeedButton;

procedure FormCreate(Sender: TObject);

procedure N1Click(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure Edit1KeyPress(Sender: TObject; var Key: Char);

procedure REd1KeyPress(Sender: TObject; var Key: Char);

procedure SG2KeyPress(Sender: TObject; var Key: Char);

procedure SB1Click(Sender: TObject);

procedure SB2Click(Sender: TObject);

procedure REd2KeyPress(Sender: TObject; var Key: Char);

procedure SB7Click(Sender: TObject);

procedure SB3Click(Sender: TObject);

procedure SB5Click(Sender: TObject);

procedure N3Click(Sender: TObject);

procedure SB4Click(Sender: TObject);

procedure SB6Click(Sender: TObject);

procedure LokBut(Sender: TObject);

procedure SpeedButton1Click(Sender: TObject);

procedure SpeedButton2Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

 

Const

DopChr = ['a'..'z', '0'..'9'];

 

var Rez:TStrings; Old1, Old2:String;

Cont:Set of Char; // Допустимые символы

Form1: TForm1;

 

Function Det0(Tb:TStringGrid):Boolean;

Function Invert(S:String; N:LongInt):String;

Function KeyR(Tb:TStringGrid; Zn:Char; N:Integer=0):Integer;

Function KeyS(Tb:TStringGrid; Zn:Char; N:Integer=0):Integer;

Function Znak(Tb:TStringGrid; C, R:LongInt):Char;

 

implementation

 

{$R *.dfm}

 

procedure TForm1.FormCreate(Sender: TObject);

Var ColL:LongInt; Lst:TStrings;

begin

Cont:= [];

ColL:= 0; // Ноль строк

Lst:=TStringList.Create;

Try

Lst.Clear;

IF FileExists(ExtractFilePath(ParamStr(0))+'Grid.cfg') Then

Lst.LoadFromFile(ExtractFilePath(ParamStr(0))+'Grid.cfg');

ColL:= Lst.Count;

Finally

SG2.RowCount:= ColL;

Lst.Free;

End;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

SG1.Visible:=False;

PC1.ActivePage:=TabSheet2;

IF FileExists(ExtractFilePath(ParamStr(0))+'Grid.cfg') Then

SG2.Cols[0].LoadFromFile(ExtractFilePath(ParamStr(0))+'Grid.cfg');

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Sg1.ColCount:= ColL;

Sg1.RowCount:= Sg1.ColCount;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

N1.Click;

 

IF(REd1.Lines.Count>0)OR(REd2.Lines.Count>0)Then SB7.Enabled:=True ELSE

SB7.Enabled:=False;

end;

 

Function Det0(Tb:TStringGrid):Boolean;

VAR R:LongInt; //Заполненость таблицы

begin

Det0:=True;

For R:=0 To Tb.RowCount-1 Do

IF Tb.Cells[0, R]='' Then

begin

Det0:=True;

ShowMessage('ЗАПОЛНИТЕ ВСЁ!'); Break;

end ELSE Det0:=False;

end;

 

procedure TForm1.N1Click(Sender: TObject);

Var R,I:LongInt; Ms, Sd:String;

begin

IF Det0(SG2) Then Exit;

//=============================================== Фильтр символов

Cont:= [];

For I:=0 To Sg2.RowCount - 1 Do

begin

Cont:= Cont + [ Znak(Sg2, 0, I) ];

end;

//===============================================

PC1.Enabled:=False;

Ms:='';

For I:=0 To Sg2.RowCount-1 Do

MS:=MS+SG2.Cells[0, I];

 

For R:=0 To SG1.RowCount-1 Do

begin

SG1.Rows[R].Clear;

 

Sd:=Invert(MS, R);

For I:=1 to Length(Sd) Do

SG1.Rows[R].Add(Sd[I]);

 

end;

 

PC1.Enabled:=True;

end;

 

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

IF Det0(Sg2) = False Then

SG2.Cols[0].SaveToFile(ExtractFilePath(ParamStr(0))+'Grid.cfg');

end;

 

Function Invert(S:String; N:LongInt):String;

Var S1,S2, Sum:String;

begin

 

IF(S='')OR(N>Length(S))Then Exit;

///////////////////////////

Try

IF N>0 Then

begin

 

S1:=''; S2:='';

S1:=Copy(S, 1, N);

S2:=Copy(S, N+1, Length(S)-N);

Sum:=S2+S1;

Invert:=Sum;

 

end ELSE

IF N<=0 Then

Begin

 

Invert:=S;

 

End;

Except

ShowMessage('ВНУТРЕНЯЯ ОШИБКА!'); Exit;

End;

end;

 

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);

begin

CASE Key OF

'А'..'Я',#8,#9:;

'а'..'я', 'a'..'z': Key:=Chr(Ord(Key)-32);

'ё','Ё': Key:='Ё';

// ELSE Key:=#0;

End;

IF Not (Key in Cont) Then Key:=#0;

end;

 

procedure TForm1.REd1KeyPress(Sender: TObject; var Key: Char);

begin

CASE Key OF

'А'..'Я',#8,#9,#13,#10,' ':;

'а'..'я', 'a'..'z': Key:=Chr(Ord(Key)-32);

'ё','Ё': Key:='Ё';

'0'..'9':;

End;

end;

 

procedure TForm1.REd2KeyPress(Sender: TObject; var Key: Char);

begin

CASE Key OF

'А'..'Я',#8,#9,#13,#10,' ':;

'а'..'я', 'a'..'z': Key:=Chr(Ord(Key)-32);

'ё','Ё': Key:='Ё';

'0'..'9':;

// ELSE Key:=#0;

End;

end;

 

procedure TForm1.SG2KeyPress(Sender: TObject; var Key: Char);

begin

CASE Key OF

'А'..'Я',#8,#9,#13,#10,' ':;

'а'..'я', 'a'..'z': Key:=Chr(Ord(Key)-32);

'ё','Ё': Key:='Ё';

'0'..'9':;

// ELSE Key:=#0;

End;

end;

 

Function KeyR(Tb:TStringGrid; Zn:Char; N:Integer=0):Integer;

Var R:LongInt; // ОБЩЕЕ: сканер столбцов

begin // Определение номера строки ключа " 1-ый столбец "

Result:=0;

For R:=0 To Tb.RowCount-1 Do

begin

Application.ProcessMessages();

IF Tb.Cells[N, R]=Zn Then Begin Result:=R; Break; End;

end;

end;

 

Function KeyS(Tb:TStringGrid; Zn:Char; N:Integer=0):Integer;

Var C:LongInt; // ОБЩЕЕ: сканер строк

begin // Определение номера столбца

Result:=0;

For C:=0 To Tb.ColCount-1 Do

begin

Application.ProcessMessages();

IF Tb.Cells[C, N]=Zn Then Begin Result:=C; Break; End;

end;

end;

 

Function Znak(Tb:TStringGrid; C, R:LongInt):Char;

begin //

Result:=Tb.Cells[C, R][1];

end;

 

procedure TForm1.SB1Click(Sender: TObject);

Var I,J,K:LongInt; Key,Txt, Oyt:String; Ch:Char; A,B:Longint;

begin // ШИФРУЕТ

IF Edit1.Text='' Then Exit;

 

Timer1.Enabled:=False;

SB1.Enabled:=False;

SB2.Enabled:=False;

Edit1.Enabled:=False;

REd2.Enabled:=False;

REd1.Enabled:=False;

 

Key:=Edit1.Text;

J:=1;

 

REd2.Lines.Clear; //Чистка

FOR K:=0 To REd1.Lines.Count-1 Do

Begin Oyt:='';

Txt:=REd1.Lines.Strings[ K ]; //Грузим строку

 

For I:=1 To Length(Txt{REd1.Lines.Text})Do

begin

Application.ProcessMessages(); //

///////////////////////////////

IF {REd1.Lines.Text[I]}Txt[I] in Cont{['А'..'Я','Ё']} Then

Begin

Ch:=Key[J];

A:=KeyR(SG1, Ch, 0); // Ищем номер символа ключа в столбце

Ch:=Txt[I]; //REd1.text[I];

B:=KeyS(SG1, Ch, 0); // Ищем номер символа текста в строке

//REd2.Text:=REd2.Text+Znak(SG1, B, A);

Oyt:=Oyt+Znak(SG1, B, A);

 

IF J<=Length(Key)-1 Then J:=J+1 ELSE J:=1; //Перебор Ключа

 

End ELSE

Begin //

Ch:=Txt[ I ];

//REd2.Text:=REd2.Text+Ch;

Oyt:=Oyt+Ch;

End;

///////////////////////////////

end;

REd2.Lines.Add(Oyt);

End;

 

SB1.Enabled:=True;

SB2.Enabled:=True;

Edit1.Enabled:=True;

Timer1.Enabled:=True;

REd2.Enabled:=True;

REd1.Enabled:=True;

end;

 

procedure TForm1.SB2Click(Sender: TObject);

Var I,J,K:LongInt; Key,Txt, Oyt:String; Ch:Char; A,B:Longint;

begin // РАСШИФРОВЫВАЕМ

IF Edit1.Text='' Then Exit;

Timer1.Enabled:=False;

SB1.Enabled:=False;

Edit1.Enabled:=False;

REd2.Enabled:=False;

REd1.Enabled:=False;

 

REd1.Clear; //Чистим

Key:=Edit1.Text;

J:=1;

 

For K:=0 To REd2.Lines.Count-1 Do

Begin Oyt:='';

Txt:=REd2.Lines.Strings[K];

Application.ProcessMessages(); //

 

For I:=1 To Length(Txt) DO

Begin

Application.ProcessMessages();

//////////////////////////////

IF Txt[I] IN Cont{['А'..'Я','Ё']} Then

Begin

Ch:=Key[J];

A:=KeyR(SG1, Ch, 0); // Ищем номер символа ключа в столбце

Ch:=Txt[I]; //REd2.text[I];

B:=KeyS(SG1, Ch, A); // Ищем номер символа текста в строке " Main "

//REd1.Text:=REd1.Text+Znak(SG1, B, 0);

Oyt:=Oyt+Znak(SG1, B, 0);

 

IF J<=Length(Key)-1 Then J:=J+1 ELSE J:=1; //Перебор Ключа

 

End ELSE

Begin

Ch:=Txt[ I ];

//REd1.Text:=REd1.Text+Ch;

Oyt:=Oyt+Ch;

End;

//////////////////////////////

End;

REd1.Lines.Add(Oyt);

End;

 

SB1.Enabled:=True;

SB2.Enabled:=True;

Edit1.Enabled:=True;

Timer1.Enabled:=True;

REd2.Enabled:=True;

REd1.Enabled:=True;

end;

 

procedure TForm1.SB7Click(Sender: TObject);

begin // Удалить всё

IF REd1.Lines.Count>0 Then REd1.Clear;

IF REd2.Lines.Count>0 Then REd2.Clear;

SB7.Enabled:=False; SB1.Enabled:=False;

SB2.Enabled:=False; SB4.Enabled:=False;

SB6.Enabled:=False;

SBar1.Panels[0].Text:='';

SBar1.Panels[1].Text:='';

end;

 

procedure TForm1.SB3Click(Sender: TObject);

begin

OD1.Title:='Открыть исходный текст...';

IF OD1.Execute Then

Begin

SBar1.Panels[0].Text:=ExtractFileName(OD1.FileName);

Old1:=OD1.FileName;

 

Application.ProcessMessages(); //

Try

SD1.FileName:=Old1;

REd1.Lines.LoadFromFile(Old1);

Except

BEEP; ShowMessage('Нет доступа к: '+Old1);

SBar1.Panels[0].Text:=''; SD1.FileName:='';

End;

OD1.FileName:='';

End;

end;

 

procedure TForm1.SB5Click(Sender: TObject);

begin

OD1.Title:='Открыть шифрованный текст...';

IF OD1.Execute Then

Begin

SBar1.Panels[1].Text:=ExtractFileName(OD1.FileName);

Old2:=OD1.FileName;

 

Application.ProcessMessages(); //

Try

REd2.Lines.LoadFromFile(Old2);

Except

BEEP; ShowMessage('Нет доступа к: '+Old2);

SBar1.Panels[1].Text:='';

End;

OD1.FileName:='';

End;

end;

 

procedure TForm1.N3Click(Sender: TObject);

begin

SG1.Visible:=Not SG1.Visible;

end;

 

procedure TForm1.SB4Click(Sender: TObject);

Label 0;

begin

SD1.Title:='Сохранить Исходный текст как...';

 

IF SBar1.Panels[0].Text='' Then

Begin

 

0: IF SD1.Execute Then

begin

Old1:=SD1.FileName;

Application.ProcessMessages();

REd1.Lines.SaveToFile(Old1);

SBar1.Panels[0].Text:=ExtractFileName(Old1);

end;

 

End ELSE

IF MessageBox(Handle, PChar('Если хотите использовать имеющийся путь'+

#13+'"'+Old1+'"'+

#13' Нажмите " Да ".'), 'Сохранение',

MB_YESNO+MB_ICONINFORMATION)=MrYes Then

REd1.Lines.SaveToFile(Old1) ELSE GoTo 0;

//SBar1.Panels[0].Text

SD1.FileName:='';

end;

 

procedure TForm1.SB6Click(Sender: TObject);

Label 1;

begin

SD1.Title:='Сохранить Зашифрованный текст как...';

 

IF SBar1.Panels[1].Text='' Then

Begin

 

1: IF SD1.Execute Then

begin

Old2:=SD1.FileName;

Application.ProcessMessages();

REd2.Lines.SaveToFile(Old2);

SBar1.Panels[1].Text:=ExtractFileName(Old2);

end;

 

End ELSE

IF MessageBox(Handle, PChar('Если хотите использовать имеющийся путь'+

#13+'"'+Old2+'"'+

#13' Нажмите " Да ".'), 'Сохранение',

MB_YESNO+MB_ICONINFORMATION)=MrYes Then

REd2.Lines.SaveToFile(Old2) ELSE GoTo 1;

//SBar1.Panels[0].Text

SD1.FileName:='';

end;

 

procedure TForm1.LokBut(Sender: TObject);

begin // Проверка текстовых полей

IF REd1.Lines.Count>0 Then

begin

SB1.Enabled:=True;

SB4.Enabled:=True;

end ELSE

IF REd1.Lines.Count<=0 Then

begin

SB1.Enabled:=False;

SB4.Enabled:=False;

end;

 

IF REd2.Lines.Count>0 Then

begin

SB2.Enabled:=True;

SB6.Enabled:=True;

end ELSE

IF REd2.Lines.Count<=0 Then

begin

SB2.Enabled:=False;

SB6.Enabled:=False;

end;

 

IF(REd1.Lines.Count>0)OR(REd2.Lines.Count>0)Then SB7.Enabled:=True ELSE

SB7.Enabled:=False;

 

TabSheet1.Caption:=Format('Таблица - [R=%d, C=%d]',

[SG1.RowCount, SG1.ColCount])

end;

 

// МЕТОДЫ ДЛЯ " STRINGGRID "

procedure DelCol(SG: TStringGrid);

Var I, J:LongInt;

begin // Удалить колонку

with SG do

begin

J:= ColCount - 1;

Cols[ J ].Clear;

for I:=J to ColCount - 2 do

Cols[ I ].Assign(Cols[ I+1 ]);

ColCount:= ColCount - 1;

end;

end;

 

procedure DelRow(SG: TStringGrid);

Var I, J:LongInt;

begin // Удалить строку

with SG do

begin

J:= RowCount - 1; // Последняя строка

Rows[ J ].Clear;

for I:=J to RowCount - 2 do

Rows[I].Assign(Rows[ I+1 ]);

RowCount:= RowCount - 1;

end;

end;

 

procedure InsRow(SG: TStringGrid);

begin // Вставка строки

With SG do

RowCount:= RowCount + 1;

end;

 

procedure InsCol(StrGrid: TStringGrid);

begin // Вставка колонок

StrGrid.ColCount:= StrGrid.ColCount + 1;

end;

 

 

procedure TForm1.SpeedButton1Click(Sender: TObject);

begin // Добавить Строку для символов

IF SG2.RowCount<256 Then

begin

InsRow(Sg2);

InsRow(Sg1);

InsCol(SG1);

end ELSE Beep;

end;

 

procedure TForm1.SpeedButton2Click(Sender: TObject);

begin // Удалить Строку для символов

IF Sg2.RowCount>33 Then

Begin

DelRow(Sg2);

DelRow(Sg1);

DelCol(SG1);

End ELSE Beep;

end;

 

end.



<== предыдущая лекция | следующая лекция ==>
Программирование микропроцессора КР580ВМ80А. Работа с внешними устройствами. | Алгоритм выполнения работы
Поделиться с друзьями:


Дата добавления: 2017-02-25; Мы поможем в написании ваших работ!; просмотров: 423 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Что разум человека может постигнуть и во что он может поверить, того он способен достичь © Наполеон Хилл
==> читать все изречения...

976 - | 886 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.009 с.