Файл: Курсовая работа Написание программы для шифрования текста с помощью шифра Уитстона.docx
Добавлен: 12.12.2023
Просмотров: 115
Скачиваний: 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);
}
Сравнение кода программ по метрике Холстеда
С++
-
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
-
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
-
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.
Библиографический список
-
https://vunivere.ru/work24054/page2 -
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 -
https://techrocks.ru/2019/01/21/about-python-briefly/ -
https://web-creator.ru/articles/php -
https://spectrum.ieee.org/top-programming-languages/ -
https://ru.wikipedia.org/wiki/Python -
https://ru.wikipedia.org/wiki/PHP