Файл: Курсовая работа Написание программы для шифрования текста с помощью шифра Уитстона.docx

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 12.12.2023

Просмотров: 90

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


Поясним на примере процедуру шифрования этим шифром. Пусть имеются две таблицы со случайно расположенными в них русскими алфавитами (рис. 5). Перед шифрованием исходное сообщение разбивают на биграммы. Каждая из них шифруется отдельно. Первую букву биграммы находят в левой таблице, а вторую ‑ в правой. Затем мысленно строят прямоугольник так, чтобы буквы биграммы лежали в его противоположных вершинах. Другие две вершины этого прямоугольника дают буквы биграммы шифртекста.

Ж

Щ

Н

Ю

Р




И

Ч

Г

Я

Т

И

Т

Ь

Ц

Б




,

Ж

Ь

М

О

Я

М

Е

.

С




З

Ю

Р

В

Щ

В

Ы

П

Ч







Ц

:

П

Е

Л

:

Д

У

О

К




Ъ

А

Н

.

Х

З

Э

Ф

Г

Ш




Э

К

С

Ш

Д

Х

А

,

Л

Ъ




Б

Ф

У

Ы




Рис. 5. Две таблицы со случайно расположенными символами русского алфавита для шифра "двойной квадрат"

Предположим, что шифруется биграмма исходного текста "ИЛ". Буква И находится в столбце 1 и строке 2 левой таблицы, буква Л находится в столбце 5 и строке 4 правой таблицы. Это означает, что прямоугольник образован строками 2 и 4, а также столбцами 1 левой таблицы и 5 правой таблицы. Следовательно, в биграмму шифртекста входят буква О, расположенная в столбце 5 и строке 2 правой таблицы, и буква В, расположенная в столбце 1 и строке 4 левой таблицы, т.е. получаем биграмму шифртекста 0В.


Если обе буквы биграммы сообщения лежат в одной строке, то и буквы шифртекста берут из той же строки. Первую букву биграммы шифртекста берут из левой таблицы в столбце, соответствующем второй букве биграммы сообщения; вторая буква берется из правой таблицы в столбце, со ответствующем первой букве биграммы сообщения. Поэтому би-грамма сообщения ТО превращается в биграмму шифртекста ЖБ. Аналогичным образом шифруются все биграммы сообщения:

Сообщение

П

Р




И

Л




Е

Т




А

Ю







Ш




Е

С




Т

О




Г

О

Шифртекст

П

Е




О

В




Щ

Н




Ф

М




Е

Ш




Р

Ф




Б

Ж




Д

Ц

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


Коды выполнения программы


C++

#include "stdafx.h"

#include

#include

#include

//Константы

const int SizeTableX=5;

const int SizeTableY=5;

const int NumberOfSymbols=25;

const int OffsetASCIISymbolStart=0x61;

typedef std::vector<:vector>> ARRAY;

//Исключение если файл не найден

class FileNotFound{};

//Класс для шифрования методом Уитсона

class Shifr{

//Таблицы для шифрования

ARRAY tables[2];

public:

Shifr::Shifr();

void Generate_Tables(); //Генерирует 2 случайные таблицы

void Crypt(char* s1, char* s2);//Шифрование и оно же дешифрование

void WriteTablesToDisk(char* FileName);//Запись сгенерированной таблицы в файл

void ReadTablesFromDisk(char* FileName);//Чтение таблицы из файла

private:

ARRAY generate_table(ARRAY);

void find_symbol_table(int table,char s,int* x,int* y);//Находит символ s в таблице с номером table и возвращает его координаты

char get_symbol_by_index(int table,int x,int y);//Находит символ по координатам в таблице table

};

Shifr::Shifr(){

for (int j=0;j<2;j++){

tables[j].resize(SizeTableX);

tables[j].resize(SizeTableX);

for (int i=0;i
tables[j][i].assign(SizeTableY,0);

tables[j][i].assign(SizeTableY,0);

}

}

}

void Shifr::Generate_Tables(){

tables[0]=generate_table(tables[0]);

tables[1]=generate_table(tables[1]);

}

ARRAY Shifr::generate_table(ARRAY t){

bool empty;

int x;

int y;

//Переборка 2 таблиц

for (int i=0;i
empty=true;

//Генерируем до тех пор, пока не попадем в еще пустое место

while (empty){

//Генерируем случайные координаты в таблице

x=rand()%SizeTableX;

y=rand()%SizeTableY;

if (t[x][y]==0){

//Пишем значение в пустой ячейке

t[x][y]=i+OffsetASCIISymbolStart;

empty=false;

}

}

}

return t;

}

void Shifr::Crypt(char* s1, char* s2){

int x,y,x1,y1;

//Ищем индексы в таблице

find_symbol_table(0,*s1,&x,&y);

find_symbol_table(1,*s2,&x1,&y1);

//На противоположных диfганалях ищем символы

*s1=get_symbol_by_index(0,x,y1);

*s2=get_symbol_by_index(1,x1,y);

}

void Shifr::find_symbol_table(int table,char s,int* x,int* y){

int i,j;

bool found=false;

for (i=0;i
for (j=0;j
if (tables[table][i][j]==s){

*x=i;

*y=j;

found=true;

}

}

}

char Shifr::get_symbol_by_index(int table,int x,int y){

return tables[table][x][y];

}

void Shifr::WriteTablesToDisk(char* FileName){

char massiv[2*SizeTableX*SizeTableY];

for (int k=0;k<2;k++)

for (int i=0;i
for (int j=0;j
massiv[k*(SizeTableX*SizeTableY)+i*SizeTableY+j]=tables[k][i][j];

FILE *file;

file = fopen(FileName,"w");

if (file==0)

throw FileNotFound();

fputs(massiv,file);

fclose(file);

}

void Shifr::ReadTablesFromDisk(char* FileName){

FILE *file;

char massiv[2*SizeTableX*SizeTableY];

file = fopen(FileName,"r");

if (file==0)

throw FileNotFound();

fgets(massiv,2*SizeTableX*SizeTableY,file);

for (int k=0;k<2;k++)

for (int i=0;i
for (int j=0;j
tables[k][i][j]=massiv[k*(SizeTableX*SizeTableY)+i*SizeTableY+j];

fclose(file);

}

int _tmain(int argc, _TCHAR* argv[])

{

Shifr t;

t.Generate_Tables();

t.WriteTablesToDisk("c:\\images\\1.txt");

char a='a';

char b='b';

//шифруем два символа

t.Crypt(&a,&b);

t.ReadTablesFromDisk("c:\\images\\1.txt");

t.Crypt(&a,&b);

return 0;

}

Python

import random

class Key:

"""

Класс для генерации и обращение с ключем.

Сам ключ представлен как две строки с перемешанным алфавитом

"""

ALPHABET_DEFAULT = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя .!,-1234567890?"

ROWS_DEFAULT = 7

COLS_DEFAULT = 7

def __init__(self, alphabet=ALPHABET_DEFAULT, rows=ROWS_DEFAULT, cols=COLS_DEFAULT):

"""

Принимает на вход символы алфавита и размер таблицы,

либо использует алфавит по умолчанию

"""

self.rows = rows

self.cols = cols

self.table = [0] * 2

for i in range(2):

self.table[i] = list(alphabet)

random.shuffle(self.table[i])

self.table[i] = ''.join(self.table[i])

def __getitem__(self, key):

"""

Если передали кортеж из двух элементов,

то это поиск символа в левой (0) или правой (1) таблице

Если передали кортеж из трех элементов,

то это получение символа в таблице по координатам

"""

if len(key) == 2:

# table and char

i = self.table[key[0]].index(key[1])

return i // self.cols, i % self.cols

else:

return self.table[key[0]][key[1] * self.cols + key[2]]

def __str__(self):

"""

Для отображения ключа в читабельном виде

"""

s = ""

for i in range(self.rows):

s += self.table[0][i * self.cols:(i + 1) * self.cols] + "\t\t" + self.table[1][

i * self.cols:(i + 1) * self.cols] + "\n"

return s

def bgrams(l):

"""

Генератор для разбиения строки на биграммы

"""

for i in range(0, len(l), 2):

yield l[i:i + 2]

def crypt(s, key):

"""

Функция шифровки/дешифровки.

Пробегаемся по всем биграммам и для каждой биграммы

находим координаты первого символа в первой таблице,

второго во второй таблице.

Далее получаем символы из противоположных вершин прямоугольника

и добавляем к строке с результатом

"""

assert len(s) % 2 == 0, "String must divedes by 2"

r = ""

for bg in bgrams(s):

(x1, y1), (x2, y2) = key[(0, bg[0])], key[(1, bg[1])]

r += key[(0, x2, y1)] + key[(1, x1, y2)]

return r

# Проверка работоспособности

key = Key()

print(key)

s = crypt("привет человек. как у тебя дела?", key)

print(s)

s = crypt(s, key)

print(s)

PHP

function dsCrypt($input,$decrypt=false) {

$o = $s1 = $s2 = array(); // Arrays for: Output, Square1, Square2

// формируем базовый массив с набором символов

$basea = array('?','(','@',';','$','#',"]","&",'*'); // base symbol set

$basea = array_merge($basea, range('a','z'), range('A','Z'), range(0,9) );

$basea = array_merge($basea, array('!',')','_','+','|','%','/','[','.',' ') );

$dimension=9; // of squares

for($i=0;$i<$dimension;$i++) { // create Squares

for($j=0;$j<$dimension;$j++) {

$s1[$i][$j] = $basea[$i*$dimension+$j];

$s2[$i][$j] = str_rot13($basea[($dimension*$dimension-1) - ($i*$dimension+$j)]);

}

}

unset($basea);

$m = floor(strlen($input)/2)*2; // !strlen%2

$symbl = $m==strlen($input) ? '':$input[strlen($input)-1]; // last symbol (unpaired)

$al = array();

// crypt/uncrypt pairs of symbols

for ($ii=0; $ii<$m; $ii+=2) {

$symb1 = $symbn1 = strval($input[$ii]);

$symb2 = $symbn2 = strval($input[$ii+1]);

$a1 = $a2 = array();

for($i=0;$i<$dimension;$i++) { // search symbols in Squares

for($j=0;$j<$dimension;$j++) {

if ($decrypt) {

if ($symb1===strval($s2[$i][$j]) ) $a1=array($i,$j);

if ($symb2===strval($s1[$i][$j]) ) $a2=array($i,$j);

if (!empty($symbl) && $symbl===strval($s2[$i][$j])) $al=array($i,$j);

}

else {

if ($symb1===strval($s1[$i][$j]) ) $a1=array($i,$j);

if ($symb2===strval($s2[$i][$j]) ) $a2=array($i,$j);

if (!empty($symbl) && $symbl===strval($s1[$i][$j])) $al=array($i,$j);

}

}

}

if (sizeof($a1) && sizeof($a2)) {

$symbn1 = $decrypt ? $s1[$a1[0]][$a2[1]] : $s2[$a1[0]][$a2[1]];

$symbn2 = $decrypt ? $s2[$a2[0]][$a1[1]] : $s1[$a2[0]][$a1[1]];

}

$o[] = $symbn1.$symbn2;

}

if (!empty($symbl) && sizeof($al))

$o[] = $decrypt ? $s1[$al[1]][$al[0]] : $s2[$al[1]][$al[0]];

return implode('',$o);

}

Сравнение кода программ по метрике Холстеда


С++

  1. NUOprtr =110

NUOprnd = 64

Noprtr =181

Noprnd =154

HPVoc = NUOprtr + NUOprnd =174

HPLen = Noprtr + Noprnd =335

HPVol = HPLen log2 HPVoc =335*7,443= 2493,4

HDiff = (NUOprtr/2) × (NOprnd / NUOprnd) =55*2,4=132

HEff = HDiff × HPVol=132*2493,4=329 128

Python

  1. NUOprtr =59

NUOprnd =45

Noprtr = 77

Noprnd = 69

HPVoc = NUOprtr + NUOprnd = 104

HPLen = Noprtr + Noprnd =146

HPVol = HPLen log2 HPVoc =146*6,7=978,2

HDiff = (NUOprtr/2) × (NOprnd / NUOprnd) =29,5*1,64=48,38

HEff = HDiff × HPVol=48,38*978,2=47 325,3

PHP

  1. NUOprtr =76

NUOprnd =71

Noprtr =102

Noprnd =84

HPVoc = NUOprtr + NUOprnd = 147

HPLen = Noprtr + Noprnd =186

HPVol = HPLen log2 HPVoc =186*7,2=1339,2

HDiff = (NUOprtr/2) × (NOprnd / NUOprnd) =38*1,18=44,84

HEff = HDiff × HPVol=44,84*1339,2=60 049,7

Вывод


Выполнив задание по написанию программ для шифрования текста с помощью шифра Уитстона на трех, рассмотренных языках (C++,Python,PHP) и стравних их по метрике Холстеда, можно прийти к выводу о том, что наиболее подходящим языком для этого является Python.

Библиографический список


  1. https://vunivere.ru/work24054/page2

  2. https://ru.wikipedia.org/wiki/%D0%A8%D0%B8%D1%84%D1%80_%D0%A3%D0%B8%D1%82%D1%81%D1%82%D0%BE%D0%BD%D0%B0

  3. https://techrocks.ru/2019/01/21/about-python-briefly/

  4. https://web-creator.ru/articles/php

  5. https://spectrum.ieee.org/top-programming-languages/

  6. https://ru.wikipedia.org/wiki/Python

  7. https://ru.wikipedia.org/wiki/PHP