Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсач вроде готовый.docx
Скачиваний:
27
Добавлен:
01.09.2019
Размер:
330.54 Кб
Скачать

2.6. Экспериментальная проверка работы программы

Для проверки работы программы, выполняющей шифрование по таблице Виженера, возьмѐм, например, слово «приветствие», а ключевым символом будет являться, например, слово «два».

После шифрования был получен следующий зашифрованный текст:

«СРМДЕЦУТЖКЕ»

Для проверки работы программы дешифрования по таблице Виженера возьмѐм этот же зашифрованный текст «СРМДЕЦУТЖКЕ». При этом ключевым символом должно являться слово «два». При расшифровке текста получим первоначальный текст «приветствие».

3. Взлом полиалфавитных шифров

Проще всего взломать полиалфавитный шифр, зная его период, то есть число используемых моноалфавитных шифров. Тогда, выбрав буквы, соответствующие каждому из моноалфавитных шифров, можно к каждому из них применить так называемый частотный анализ (или какой-нибудь другой метод взлома моноалфавитных шифров). Метод основан на том, что каждая буква в произвольном тексте появляется с вполне определѐнной частотой, а значит, посмотрев частоты появления тех или иных букв, можно узнать, как происходит замена. Одним из методов нахождения периода полиалфавитных шифров является метод, предложенный Фредериком Касиски в 1836 году. Он заключается в том, что в зашифрованном тексте находятся одинаковые сегменты длины не меньше, чем три буквы, затем вычисляются расстояния между первыми буквами соседних сегментов. Оказывается, предполагаемый период является кратным наибольшему общему делителю для этих расстояний.

Заключение

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

Delphi ("Делфи").

Также была выполнена экспериментальная проверка работы данной программы, подтверждающая правильность шифрования.

С развитием ЭВМ полиалфавитные шифры перестали быть столь устойчивыми к криптоатакам, и, так же, как в своѐ время и моноалфавитные шифры, отошли на задний план, став частью истории.

Список используемой литературы

  1. А.В. Яковлев, А.А. Безбогов, В.В. Родин, В.Н. Шамкин. Криптографическая защита информации. — Тамбов: Издательство ТГТУ,

2006

  1. David, Kahn. On the Origin of a Species. The Codebreakers: The Story of Secret Writing. Simon & Schuster, 1999

  1. Henk C.A. van Tilborg, ed. Encyclopedia of Cryptography and Security (First ed.). Springer. pp. 115, 2005

  1. Э. М. Габидулин. Курс лекций по Защите Информации. — Москва: Издательство МФТИ, 2007

  1. А. П. Алферов, А. Ю. Зубов, А. С. Кузьмин, А. В. Черѐмушкин. Основы криптографии. — Москва: Издательство Гелиос АРВ, 2005

Приложение А. Шифр Виженера

unit TablVin;

interface

uses

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

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

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;

Label2: TLabel;

Label3: TLabel;

Label4: TLabel;

Button1: TButton;

Button2: TButton;

N4: TMenuItem;

Label5: TLabel;

Button3: TButton;

Button4: TButton;

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);

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure N4Click(Sender: TObject);

procedure Button3Click(Sender: TObject);

procedure Button4Click(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.Button1Click(Sender: TObject);

begin

form2.showmodal;

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

SG1.Visible:=Not SG1.Visible;

end;

procedure TForm1.Button3Click(Sender: TObject);

begin

PC1.ActivePage:=TabSheet1;

end;

procedure TForm1.Button4Click(Sender: TObject);

begin

PC1.ActivePage:=TabSheet2;

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.N4Click(Sender: TObject);

begin

ShowMessage('Логвинов М.Ю 313ПИ Курсовая на тему:"Шифрование Вижинера" 2012');

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;

label5.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.

Приложение Б. Скриншоты программы

Приложение В. Квадрат Виженера (tabula recta)

A

B

C

D

E

F

G

H

I

J

K

L

M N

O P

Q

R S

T

U V

W X

Y

Z

A

A

B

C

D

E

F

G

H

I

J

K

L

M N

O P

Q

R S

T

U V

W X

Y

Z

B

B

C

D

E

F

G

H

I

J

K

L

M N O P

Q

R

S

T

U

V W X Y

Z

A

C

C

D

E F

G

H

I

J

K

L

M N

O P

Q

R S

T

U V

W X

Y Z

A

B

D

D

E

F

G

H

I

J

K

L

M N O P

Q

R

S

T

U

V W X Y

Z

A

B

C

E

E

F

G

H

I

J

K

L

M N

O P

Q

R S

T

U

V

W X

Y Z

A

B

C

D

F

F

G

H I

J

K

L

M N O P

Q

R

S

T

U

V

W X Y

Z

A

B

C

D

E

G

G

H

I J

K

L

M N O P

Q

R

S

T

U V

W X

Y Z

A

B

C

D

E

F

H

H

I

J

K

L

M N O P

Q

R

S

T

U

V W X Y

Z

A

B

C

D

E

F

G

I

I

J

K

L

M N

O P

Q

R S

T

U

V

W X

Y

Z

A

B

C

D

E

F

G

H

J

J

K

L

M N

O P

Q

R

S

T

U

V

W X

Y

Z

A

B

C

D

E

F

G

H

I

K

K

L

M N O P

Q

R

S

T

U V

W X

Y

Z

A

B

C

D

E

F

G

H

I

J

L

L

M N

O P

Q

R

S

T

U

V W X Y

Z

A

B

C

D

E

F

G

H

I

J

K

M

M N O P

Q

R

S

T

U V W X Y Z

A

B

C

D

E

F

G

H

I

J

K

L

N

N O P

Q

R

S

T

U V W X Y

Z

A

B

C

D

E

F

G

H

I

J

K

L

M

O

O P

Q

R

S

T

U V W X

Y Z

A

B

C

D

E

F

G

H

I

J

K

L

M N

P

P

Q

R S

T

U

V W X Y

Z

A

B

C

D

E F

G

H

I

J

K

L

M N O

Q

Q

R

S

T

U V W X Y Z

A

B

C

D

E

F

G

H

I

J

K

L

M N

O P

R

R

S

T

U V W X Y Z

A

B

C

D

E F

G

H

I

J

K

L

M N O P

Q

S

S

T

U

V W X

Y Z

A

B

C

D

E

F

G

H I J

K

L

M N

O P

Q

R

T

T

U V

W X Y

Z

A

B

C

D

E

F

G

H

I J

K

L

M N O P

Q

R

S

U

U V W X Y Z

A

B

C

D

E

F

G

H I J

K

L

M N

O P

Q

R

S

T

V

V W X

Y Z

A

B

C

D

E F

G

H

I J

K

L

M N O P

Q

R

S

T

U

W

W X Y

Z

A

B

C

D

E

F

G

H

I

J

K

L

M N O P

Q

R

S

T

U V

X

X Y Z

A

B

C

D

E

F

G

H

I

J

K

L

M N O P

Q

R

S

T

U

V W

Y

Y Z

A

B

C

D

E

F

G

H I

J

K

L

M N

O P

Q

R

S

T

U

V

W X

Z

Z

A

B

C

D

E

F

G

H

I J

K

L

M N O P

Q

R

S

T

U

V

W X Y

3