русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

СПОСОБЫ ШИФРОВАНИЯ И ДЕШИФРОВАНИЯ ТЕКСТА


Дата добавления: 2014-09-29; просмотров: 20597; Нарушение авторских прав


 

Введение

Криптография – наука о методах обеспечения конфиденциальности (невозможности прочтения информации посторонним) и аутентичности (целостности и подлинности авторства, а также невозможности отказа от авторства) информации.

История криптографии по существу равна по возрасту истории существования письменности, потому что именно с появлением письменности возникла потребность придумывать различные способы для хранения информации в виде, доступном только для определенного круга лиц. До нашей эры был придуман «Шифр Цезаря», который заключался в замене каждого символа в тексте на символ, отстоящий от него в алфавите на фиксированное число позиций. Криптоаналитики искали способы расшифровывать закодированные сообщения. Криптографы (шифровальщики) и криптоаналитики (дешифровальщики) находились в постоянном противоборстве: первые постоянно придумывали новые шифры, с первого взгляда недоступные для криптоаналитиков, а вторые находили способы дешифрования скрытых сообщений.

Современная криптография образует отдельное научное направление на стыке математики и информатики. Практическое применение криптографии стало неотъемлемой частью жизни современного общества – её используют в таких отраслях, как электронная коммерция, электронный документооборот (включая цифровые подписи), телекоммуникации и других.

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

Алгоритмы шифрования и дешифрования

По треугольнику Паскаля



Треугольник Паскаля – арифметический равнобедренный треугольник (рис.4.1), образованный биномиальными коэффициентами:

В треугольнике Паскаля на вершине и по бокам стоят единицы. Каждое число равно сумме двух расположенных над ним чисел. Строки треугольника симметричны относительно вертикальной оси. Продолжать треугольник можно бесконечно.

Шифрование происходит по следующему алгоритму:

из предложения выделяется очередное слово;

0: 1

1: 1 1

2: 1 2 1

3: 1 3 3 1

4: 1 4 6 4 1

5: 1 5 10 10 5 1

6: 1 6 15 20 15 6 1

7: 1 7 21 35 35 21 7 1

8: 1 8 28 56 70 56 28 8 1

9: 1 9 36 84 126 126 84 36 9 1

10: 1 10 45 120 210 252 210 120 45 10 1

11: 1 11 55 165 330 462 462 330 165 55 11 1

12: 1 12 66 220 495 792 924 792 495 220 66 12 1

13: 1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1

14: 1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1

Рис.4.1 – первые 15 строк треугольника Паскаля.

 

1.из треугольника Паскаля выбирается строка с номером, равным числу букв в слове;

2.k-я буква исходного слова заменяется на букву, отстоящую от исходной на число букв, указанное в k-м столбце выбранной строки треугольника Паскаля (отсчет производится по часовой стрелке, как показано на рис.4.2).

А Б В Г Д Е Ж З

Я И

Ю Й

Э К

Ь Л

Ы М

Ъ Н

Щ О

Ш П

Ч Ц Х Ф У Т С Р

Рис.4.2 – схема отсчета

Алгоритм дешифрования отличается только направлением отсчета: он будет обратным, т.е. против часовой стрелки.

Метод Гронсфельда

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

По матрице Виженера

Матрица Виженера представлена на рис.4.3. Применительно к шифру Цезаря каждая шифруемая буква сдвигалась бы на три строки (сдвиг +3), т.е. А стало бы Г, Б стало бы Д и т.д. Здесь же сдвиг зависит от буквы ключа.

 

  А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
А А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
Б Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А
В В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б
Г Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В
Д Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г
Е Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д
Ж Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е
З З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж
И И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З
Й Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И
К К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й
Л Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К
М М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л
Н Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М
О О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н
П П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О
Р Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П
С С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р
Т Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С
У У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т
Ф Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У
Х Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф
Ц Ц Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х
Ч Ч Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц
Ш Ш Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч
Щ Щ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш
Ъ Ъ Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ
Ы Ы Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ
Ь Ь Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы
Э Э Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь
Ю Ю Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э
Я Я А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю

Рис.4.3 – матрица Виженера

 

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

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

Если буквы А-Я соответствуют числам 1-32 (без буквы Ё), то шифрование и дешифрование по матрице Виженера можно записать в виде формул соответственно:

,

,

где - буква зашифрованного текста, - буква исходного текста, - буква ключа.

 

Проектирование приложения.

Выбор, размещение и задание свойств компонентов.

Коды классов, функций и обработчиков событий

1.Интерфейс проектируемого приложения должен удовлетворять требованиям:

· интерфейс должен быть удобен и прост в использовании;

· интерфейс должен соответствовать принципу универсальности, который подразумевает поддержание основных правил построения интерфейса, характерных для основных диалоговых систем; при этом предполагается единообразие управления, единообразие назначения элементов;

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

2.Сохраните модуль главной формы под именем LR_4, а проект – под именем PR_LR_4. Главная форма приложения представлена на рис.4.4. В свойство Caption главной формы занесено ШИФРОВАНИЕ / ДЕШИФРОВАНИЕ ДЛЯ ВВОДА ДОПУСТИМЫ ПРОПИСНЫЕ РУССКИЕ БУКВЫ И СИМВОЛ-РАЗДЕЛИТЕЛЬ ‘_’. Главное меню содержит раздел Файл (с подразделами Открыть исходный текст, Открыть шифрованный текст, Выход), раздел Операции (с подразделами Инициализация, Очистка полей) и раздел Справка (с подразделом О программе). Для подраздела Очистка полей свойство Enabled имеет значение false.

Рис.4.4 – главная форма по окончании проектирования

 

3.Наиболее часто употребляемые команды главного меню (Выход, Инициализация, Очистка полей) продублированы на инструментальной панели, расположенной под главным меню. Здесь используется простейшая по проектированию инструментальная панель. Она состоит из простой панели Panel1 (страница Стандарт) с зачищенным свойством Caption, на которой размещены три кнопки SpeedButton1,2,3 (страница Дополнительно). Двум из них даны осмысленные имена: sbtnInit (SpeedButton2), sbtnClear (SpeedButton3) (см. заголовочный файл модуля главной формы LR_4.h). Пиктограммы (изображения) помещены на кнопки через свойство Glyph соответственно из файлов dooropen, check, clear в папке …Program Files\Common Files\Borland Shared\Images\Buttons. В свойство Hint кнопок занесены соответственно всплывающие подсказки выход, инициализация, очистка полей, в свойство ShowHint – true. Для кнопки SpeedButton3 (очистка полей) свойство HelpType поставлено в значение htKeyword (режим полной подсказки).

4.Перенесите на форму (страница Диалоги) компоненты SaveDialog1 и OpenDialog1, а со страницы Стандарт - компонент PopupMenu1. Двойным щелчком на компоненте PopupMenu1 перейдите в Конструктор Меню (окно Form1->PopupMenu1) и внесите разделы Сохранить и Сохранить как.

5.Остальная часть главной формы делится на три примерно равные части компонентами - панелями GroupBox1,2,3 (страница Стандарт). В свойство Caption панелей внесено соответственно: Треугольник Паскаля, Метод Гронсфельда, По матрице.

6.На панели GroupBox1 размещены две метки Label1,2 (Исходный текст, Зашифрованный текст), два компонента Memo1,2 и две кнопки Button1,2 (страница Стандарт) с надписями (Шифрование, Дешифрование). Заданные средой имена (значение свойства Name) Memo1, Memo2 заменены на осмысленные имена: TextPascal, CodedTextPascal (см. LR_4.h). В свойство PopupMenu компонента Memo1 занесено значение PopupMenu1, что позволит через Memo1 задавать идентичный исходный текст для всех трех способов шифрования. Заданные средой имена (значение свойства Name) Button1, Button2 заменены на осмысленные – btnEncryptP, btnDecryptP, а свойству Enabled присвоено значение false.

7.На панели GroupBox2 размещены три метки Label3,4,5 (Ключ (3-8 цифр), Исходный текст, Зашифрованный текст), три компонента Memo3,4,5 (заданные средой имена заменены на edtKeyG, TextG, CodedTextG) и две кнопки Button3,4 (заданные средой имена заменены на btnEncryptG, btnDecryptG, свойство Enabled - false).

8.На панели GroupBox3 размещены три метки Label6,7,8 (Ключ (буквы), Исходный текст, Зашифрованный текст), три компонента Memo6,7,8 (заданные средой имена заменены на edtKeyM, TextM, CodedTextM) и две кнопки Button5,6 (заданные средой имена заменены на btnEncryptM, btnDecryptM, свойство Enabled - false).

 

Рис.4.5 – форма «О программе»

Рис.4.6 – главная форма с результатами тестирования

 

Рис.4.7 – окно Редактора Кода с окном Исследователя Классов

(начало структуры проекта)

Рис.4.8 – окно Редактора Кода с окном Исследователя Классов

(продолжение структуры проекта)

 

Рис.4.9 – окно Редактора Кода с окном Исследователя Классов

(окончание структуры проекта)

 

9.Перейдем к изучению кода приложения. В проекте использован модуль, не связанный с какой-либо формой. Чтобы создать такой модуль, нужно выполнить команду Файл/Новый/Другое… и открывшемся окне Новые элементы на странице Новый щелкнуть на пиктограмме Модуль. Модулю дано имя main. В заголовочном файле этого модуля main.h размещено объявление класса, а в файле реализации модуля main.cpp – реализация класса (определения функций-элементов класса).

10.Для работы с проектом большие удобства пользователю предоставляет Исследователь Классов. По умолчанию окно Исследователя Классов (рис.4.7,8,9) появляется автоматически встроенным в окно Редактора Кода. (Оно закрывается щелчком на крестике и открывается командой Вид|ClassExplorer.) В окне Исследователя Классов можно видеть структуру своего проекта, модулей и классов. Если в окне Исследователя Классов сделать двойной щелчок на имени класса, функции или переменной, то курсор в окне Редактора Кода перейдет на строку, в которой этот класс, функция или переменная объявлена. Такая возможность относится ко всем файлам проекта, в том числе и к файлам модулей, которые не связаны с какой-либо формой. Например, на рис.4.7 представлен случай, когда двойным щелчком на имени Codec файл main.h был загружен в окно Редактора Кода.

11.Заголовочный файл main.h модуля main

//---------------------------------------------------------------------------

 

#ifndef mainH

#define mainH

//---------------------------------------------------------------------------

//класс шифрования/дешифрования текста

class Codec

{

char* text; //исходный текст

char* codedtext; //зашифрованный текст

int** Ptriangle; // треугольник Паскаля

int keyG[9]; //ключ для шифра Гронсфельда, в нулевом байте –

// длина ключа

char* keyM; //ключ для шифра по матрице

public:

Codec(); //конструктор

~Codec(); //деструктор

void SetText(char* text); //задать исходный текст

char* GetText(); //получить исходный текст

void SetCodedText(char* text);//задать шифрованный текст

char* GetCodedText(); //получить шифрованный текст

void SetKeyG(char* strkey); //задать ключ для метода Гронсфельда

void SetKeyM(char* strkey); //задать ключ для шифрования по матрице

int TextLen(); //получить длину исходного текста

int CodedTextLen(); //получить длину шифрованного текста

void EncryptP(); //шифровать по треугольнику Паскаля

void EncryptM(); //шифровать по матрице

void EncryptG(); //шифровать методом Гронсфельда

void DecryptP(); //дешифровать по треугольнику Паскаля

void DecryptM(); //дешифровать по матрице

void DecryptG(); //дешифровать методом Гронсфельда

} *A; //указатель на объект класса

#endif

 

12.Файл реализации main.cpp модуля main

 

//---------------------------------------------------------------------------

 

 

#pragma hdrstop

 

#include "main.h"

#include<string.h>

 

//---------------------------------------------------------------------------

 

#pragma package(smart_init)

//Примем, что в исходном тексте не встретится слов, содержащих более //30 букв. Будем строить треугольник Паскаля для такого количества //строк

const int N = 30;

//Конструктор. Строится треугольник Паскаля и инициализируются //остальные данные-элементы класса

Codec::Codec()

{

//выделяем память под треугольник

Ptriangle = new int*[N];

for(int i = 0; i < N; i++) Ptriangle[i] = new int[i+1];

//заполняем треугольник числами

Ptriangle[0][0] = 1;

Ptriangle[1][0] = 1;

Ptriangle[1][1] = 1;

for(int i = 2; i < N; i++)

{

Ptriangle[i][0] = 1;

Ptriangle[i][i] = 1;

for(int j=1; j<i; j++)

Ptriangle[i][j] = Ptriangle[i-1][j-1] + Ptriangle[i-1][j];

}

//выделяем память под тексты и ключ

text = new char[1];

codedtext = new char[1];

keyM = new char[1];

}

 

//Деструктор

Codec::~Codec()

{

//чистим память от исходного текста

delete [] text;

//от зашифрованного текста

delete [] codedtext;

//от ключа для шифрования по матрице

delete [] keyM;

 

//чистим память от треугольника

for(int i = 0; i < N; i++) delete [] Ptriangle[i];

delete [] Ptriangle;

}

 

//задаем исходный текст

void Codec::SetText(char* text)

{

delete [] this->text;

this->text = new char[strlen(text) + 1];//плюс один для нулевого байта

strcpy(this->text,text);

}

 

//получаем исходный текст

char* Codec::GetText()

{return text;}

 

//задаем шифрованный текст

void Codec::SetCodedText(char* text)

{

this->codedtext = new char[strlen(text) + 1];

strcpy(this->codedtext,text);

}

 

//получаем зашифрованный текст

char* Codec::GetCodedText()

{return codedtext;}

 

//задаем ключ для шифра Гронсфельда

void Codec::SetKeyG(char* strkey)

{

keyG[0] = strlen(strkey);

for(int i = 0; i < keyG[0]; i++)

keyG[i+1] = strkey[i] - '0';

}

 

//задаем ключ для шифра по матрице

void Codec::SetKeyM(char* strkey)

{

delete [] keyM;

keyM = new char[strlen(strkey) + 1];

strcpy(keyM,strkey);

}

 

//получаем длину исходного текста

int Codec::TextLen()

{return strlen(text);}

 

//получаем длину зашифрованного текста

int Codec::CodedTextLen()

{return strlen(codedtext);}

 

//шифруем по треугольнику Паскаля

void Codec::EncryptP()

{

delete [] codedtext;

codedtext = new char[strlen(text) + 1];

char word[N + 1] = {'\0'},//слово

*t, //указатель на текущую букву в исходном тексте

*ct; //указатель на текущую букву в зашифрованном тексте

bool flag = true;//признак достижения конца текста

t = text;

ct = codedtext;

 

//пока не достигли конца текста

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *t++)

{

if(word[i] == '_')

{

word[i] = '\0'; break;

}

i++;

}

//шифруем слово по треугольнику Паскаля

for(int j = 0; j < i; j++)

{

//на сколько будет отстоять зашифрованная буква

int n = Ptriangle[i - 1][j] % 32;

//получаем зашифрованную букву

*ct = word[j] + n;

//если вышли за пределы алфавита, то сдвиг по кругу

if(*ct > 'Я') *ct -= 32;

//сдвигаем указатель на следующую букву

ct++;

}

//после слова добавляем символ-разделитель

*ct++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец зашифрованного текста

*--ct = '\0';

}

 

//дешифруем текст, зашифрованный по треугольнику Паскаля

void Codec::DecryptP()

{

delete [] text;

text = new char[strlen(codedtext) + 1];

char word[N + 1] = {'\0'},//слово

*t, //указатель на текущую букву в исходном тексте

*ct; //указатель на текущую букву в зашифрованном тексте

bool flag = true;//признак достижения конца текста

t = text;

ct = codedtext;

 

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *ct++)

{

if(word[i] == '_')

{

word[i] = '\0'; break;

}

i++;

}

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

for(int j = 0; j < i; j++)

{

int n = Ptriangle[i-1][j] % 32;

*t = word[j] - n;

if(*t < 'А') *t += 32;

t++;

}

//после слова добавляем символ-разделитель

*t++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец дешифрованного текста

*--t = '\0';

}

 

//шифрование методом Гронсфельда

void Codec::EncryptG()

{

delete [] codedtext;

codedtext = new char[strlen(text)];

char word[N + 1] = {'\0'},//слово

*t = text, //указатель на текущую букву в исходном тексте

*ct = codedtext;//указатель на текущую букву в зашифрованном

//тексте

bool flag = true; //признак достижения конца текста

int k = 1;

 

//пока не достигли конца текста

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *t++)

{

if(word[i] == '_')

{

word[i] = '\0'; break;

}

i++;

}

 

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

for(int j = 0; j < i; j++)

{

//получаем зашифрованную букву

*ct = word[j] + keyG[k++];

//чтобы не выйти за пределы алфавита

if(*ct > 'Я') *ct -= 32;

//сдвигаем указатель на следующую букву

ct++;

//используем ключ циклически

if(k > keyG[0]) k = 1;

}

//после слова добавляем символ-разделитель

*ct++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец зашифрованного текста

*--ct = '\0';

}

 

//дешифрование методом Гронсфельда

void Codec::DecryptG()

{

delete [] text;

text = new char[strlen(codedtext) + 1];

char word[N + 1] = {'\0'},//слово

*t = text, //указатель на текущую букву в исходном тексте

*ct = codedtext;//указатель на текущую букву в зашифрованном

//тексте

bool flag = true; //признак достижения конца текста

int k = 1;

 

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *ct++)

{

if(word[i] == '_')

{

word[i] = '\0'; break;

}

i++;

}

 

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

for(int j = 0; j < i; j++)

{

*t = word[j] - keyG[k++];

if(*t < 'А') *t += 32;

t++;

if(k > keyG[0]) k = 1;

}

//после слова добавляем символ-разделитель

*t++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец дешифрованного текста

*--t = '\0';

}

 

//шифрование по матрице

void Codec::EncryptM()

{

delete [] codedtext;

codedtext = new char[strlen(text) + 1];

char word[N + 1] = {'\0'},//слово

*t = text, //указатель на текущую букву в исходном тексте

*ct = codedtext;//указатель на текущую букву в зашифрованном

//тексте

bool flag = true; //признак достижения конца текста

int k = 0;

int keylen = strlen(keyM);

 

//пока не достигли конца текста

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *t++)

{

if(word[i] == '_')

{

word[i] = '\0'; break;

}

i++;

}

 

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

for(int j = 0; j < i; j++)

{

//вычитаем два раза А, чтобы получить именно номер буквы,

//затем к остатку от деления на количество букв прибавляем А,

//чтобы получить ASCII код буквы

*ct++ = (word[j] + keyM[k++] - 'А' - 'А') % 32 + 'А';

if(k == keylen) k = 0;

}

//после слова добавляем символ-разделитель

*ct++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец зашифрованного текста

*--ct = '\0';

}

 

//дешифрование по матрице

void Codec::DecryptM()

{

delete [] text;

text = new char[strlen(codedtext) + 1];

char word[N + 1] = {'\0'},//слово

*t = text, //указатель на текущую букву в исходном тексте

*ct = codedtext;//указатель на текущую букву в зашифрованном

//тексте

bool flag = true; //признак достижения конца текста

int k = 0;

int keylen = strlen(keyM);

 

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *ct++)

{

if(word[i] == '_')

{

word[i] = '\0'; break;

}

i++;

}

 

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

for(int j = 0; j < i; j++)

{

*t++ = (word[j] - keyM[k++] + 32) % 32 + 'А';

if(k == keylen) k = 0;

}

//после слова добавляем символ-разделитель

*t++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец дешифрованного текста

*--t = '\0';

}

 

13.Заголовочный файл LR_4.h модуля LR_4 главной формы Form1

 

//---------------------------------------------------------------------------

 

#ifndef LR_4H

#define LR_4H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <Menus.hpp>

#include <Buttons.hpp>

#include <ExtCtrls.hpp>

#include <Dialogs.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published: // IDE-managed Components

TGroupBox *GroupBox1;

TGroupBox *GroupBox2;

TGroupBox *GroupBox3;

TLabel *Label1;

TMemo *TextPascal;

TLabel *Label2;

TMemo *CodedTextPascal;

TButton *btnEncryptP;

TButton *btnDecryptP;

TLabel *Label3;

TMemo *edtKeyG;

TLabel *Label4;

TMemo *TextG;

TLabel *Label5;

TMemo *CodedTextG;

TButton *btnEncryptG;

TButton *btnDecryptG;

TLabel *Label6;

TMemo *edtKeyM;

TLabel *Label7;

TMemo *TextM;

TLabel *Label8;

TMemo *CodedTextM;

TButton *btnEncryptM;

TButton *btnDecryptM;

TMainMenu *MainMenu1;

TMenuItem *N1;

TMenuItem *N2;

TMenuItem *N3;

TMenuItem *N4;

TMenuItem *N5;

TMenuItem *N6;

TMenuItem *N7;

TMenuItem *N8;

TMenuItem *N9;

TPanel *Panel1;

TSpeedButton *sbtnInit;

TSpeedButton *sbtnClear;

TSpeedButton *SpeedButton1;

TOpenDialog *OpenDialog1;

TSaveDialog *SaveDialog1;

TPopupMenu *PopupMenu1;

TMenuItem *N10;

TMenuItem *N11;

void __fastcall SpeedButton1Click(TObject *Sender);

void __fastcall N6Click(TObject *Sender);

void __fastcall N9Click(TObject *Sender);

void __fastcall sbtnInitClick(TObject *Sender);

void __fastcall N7Click(TObject *Sender);

void __fastcall sbtnClearClick(TObject *Sender);

void __fastcall N8Click(TObject *Sender);

void __fastcall N4Click(TObject *Sender);

void __fastcall N5Click(TObject *Sender);

void __fastcall btnEncryptPClick(TObject *Sender);

void __fastcall btnDecryptPClick(TObject *Sender);

void __fastcall btnEncryptGClick(TObject *Sender);

void __fastcall btnDecryptGClick(TObject *Sender);

void __fastcall btnEncryptMClick(TObject *Sender);

void __fastcall btnDecryptMClick(TObject *Sender);

void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

void __fastcall N10Click(TObject *Sender);

void __fastcall N11Click(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

 

14.Файл реализации LR_4.cpp модуля LR_4 главной формы Form1

 

//---------------------------------------------------------------------------

 

#include <vcl.h>

#pragma hdrstop

 

#include "LR_4.h"

#include "main.h"

#include <stdio.h>

#include "about.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

//очистка полей

TextPascal->Text = "";

CodedTextPascal->Text = "";

edtKeyG->Text = "";

TextG->Text = "";

CodedTextG->Text = "";

edtKeyM->Text = "";

TextM->Text = "";

CodedTextM->Text = "";

}

//---------------------------------------------------------------------------

//способы шифрования

//1 - по треугольнику Паскаля

//2 - методом Гронсфельда

//3 - по матрице

int methods[3] = {1,2,3};

//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)

{

Close();

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::N6Click(TObject *Sender)

{

exit(0);

}

//---------------------------------------------------------------------------

//инициализация

 

void __fastcall TForm1::sbtnInitClick(TObject *Sender)

{

//создание экземпляра класса

A = new Codec();

//активирование кнопок

btnEncryptP->Enabled = true;

btnDecryptP->Enabled = true;

btnEncryptG->Enabled = true;

btnDecryptG->Enabled = true;

btnEncryptM->Enabled = true;

btnDecryptM->Enabled = true;

//деактивация инициализации и активация очистки

sbtnInit->Enabled = false;

sbtnClear->Enabled = true;

N7->Enabled = false;

N8->Enabled = true;

 

}

//---------------------------------------------------------------------------

//инициализация

void __fastcall TForm1::N7Click(TObject *Sender)

{

sbtnInitClick(Sender);

}

//---------------------------------------------------------------------------

//очистка полей формы и освобождение памяти из-под объекта класса

void __fastcall TForm1::sbtnClearClick(TObject *Sender)

{

//удаление экземпляра класса

delete A;

//деактивация кнопок

btnEncryptP->Enabled = false;

btnDecryptP->Enabled = false;

btnEncryptG->Enabled = false;

btnDecryptG->Enabled = false;

btnEncryptM->Enabled = false;

btnDecryptM->Enabled = false;

//очистка полей

TextPascal->Text = "";

CodedTextPascal->Text = "";

edtKeyG->Text = "";

TextG->Text = "";

CodedTextG->Text = "";

edtKeyM->Text = "";

TextM->Text = "";

CodedTextM->Text = "";

//активация инициализации и деактивация очистки

sbtnInit->Enabled = true;

sbtnClear->Enabled = false;

N7->Enabled = true;

N8->Enabled = false;

}

//---------------------------------------------------------------------------

//очистка

void __fastcall TForm1::N8Click(TObject *Sender)

{

sbtnClearClick(Sender);

}

//---------------------------------------------------------------------------

//открытие файла с исходным текстом

void __fastcall TForm1::N4Click(TObject *Sender)

{

if(OpenDialog1->Execute())

{

FILE *fp = fopen(OpenDialog1->FileName.c_str(), "r");

//определяем размер текста

fseek(fp, 0, SEEK_END);

int textlen = ftell(fp);

fseek(fp, 0, SEEK_SET);

 

char* str = new char[textlen + 1];

fgets(str, textlen + 1, fp);

fclose(fp);

TextPascal->Text = str;

TextG->Text = str;

TextM->Text = str;

delete [] str;

}

}

//---------------------------------------------------------------------------

//открытие файла с зашифрованным текстом

void __fastcall TForm1::N5Click(TObject *Sender)

{

if(OpenDialog1->Execute())

{

FILE *fp = fopen(OpenDialog1->FileName.c_str(), "rb");

 

//считывание из файла количества символов в тексте

int textlen;

fread(&textlen, sizeof(int), 1, fp);

 

//инфа о методе, которым зашифрован текст

int method;

fread(&method, sizeof(int), 1, fp);

 

//считываем сам зашифрованный текст

char *str = new char[textlen + 1];

fread(str, sizeof(char), textlen, fp);

str[textlen] = '\0';

 

fclose(fp);

 

switch(method)

{

case 1: CodedTextPascal->Text = str; break;

case 2: CodedTextG->Text = str; break;

case 3: CodedTextM->Text = str; break;

}

delete [] str;

}

}

//---------------------------------------------------------------------------

//шифрование текста по треугольнику Паскаля

void __fastcall TForm1::btnEncryptPClick(TObject *Sender)

{

A->SetText(TextPascal->Text.c_str());

A->EncryptP();

CodedTextPascal->Text = A->GetCodedText();

 

//открываем диалог сохранения в файле

if(SaveDialog1->Execute())

{

FILE *fp = fopen(SaveDialog1->FileName.c_str(), "wb");

int codedtextlen = A->CodedTextLen();

//записываем в файл количество зашифрованных символов

fwrite(&codedtextlen, sizeof(int), 1, fp);

//способ шифрования

fwrite(&methods[0], sizeof(int), 1, fp);

//зашифрованный текст

fwrite(A->GetCodedText(), sizeof(char), codedtextlen, fp);

fclose(fp);

}

}

//---------------------------------------------------------------------------

//дешифрование текста, зашифрованного по треугольнику Паскаля

void __fastcall TForm1::btnDecryptPClick(TObject *Sender)

{

A->SetCodedText(CodedTextPascal->Text.c_str());

A->DecryptP();

TextPascal->Text = A->GetText();

}

//---------------------------------------------------------------------------

//шифрование текста методом Гронсфельда

void __fastcall TForm1::btnEncryptGClick(TObject *Sender)

{

if(edtKeyG->Text.Length() < 3)

{

MessageBox(NULL, "Длина ключа мала!", "Ошибка", 0);

return;

}

else if(edtKeyG->Text.Length() > 8)

{

MessageBox(NULL, "Длина ключа велика!", "Ошибка", 0);

return;

}

A->SetKeyG(edtKeyG->Text.c_str());

A->SetText(TextG->Text.c_str());

A->EncryptG();

CodedTextG->Text = A->GetCodedText();

 

//открываем диалог сохранения в файле

if(SaveDialog1->Execute())

{

FILE *fp = fopen(SaveDialog1->FileName.c_str(), "wb");

int codedtextlen=A->CodedTextLen();

//записываем в файл количество зашифрованных символов

fwrite(&codedtextlen, sizeof(int), 1, fp);

//способ шифрования

fwrite(&methods[1], sizeof(int), 1, fp);

//зашифрованный текст

fwrite(A->GetCodedText(), sizeof(char), codedtextlen, fp);

fclose(fp);

}

}

//---------------------------------------------------------------------------

//дешифрование текста методом Гронсфельда

void __fastcall TForm1::btnDecryptGClick(TObject *Sender)

{

if(edtKeyG->Text.Length() < 3)

{

MessageBox(NULL, "Длина ключа мала!", "Ошибка", 0);

return;

}

else if(edtKeyG->Text.Length() > 8)

{

MessageBox(NULL, "Длина ключа велика!", "Ошибка", 0);

return;

}

A->SetKeyG(edtKeyG->Text.c_str());

A->SetCodedText(CodedTextG->Text.c_str());

A->DecryptG();

TextG->Text = A->GetText();

}

//---------------------------------------------------------------------------

//шифрование по матрице

void __fastcall TForm1::btnEncryptMClick(TObject *Sender)

{

A->SetKeyM(edtKeyM->Text.c_str());

A->SetText(TextM->Text.c_str());

A->EncryptM();

CodedTextM->Text = A->GetCodedText();

 

//открываем диалог сохранения в файле

if(SaveDialog1->Execute())

{

FILE *fp = fopen(SaveDialog1->FileName.c_str(), "wb");

int codedtextlen = A->CodedTextLen();

//записываем в файл количество зашифрованных символов

fwrite(&codedtextlen, sizeof(int), 1, fp);

//способ шифрования

fwrite(&methods[2], sizeof(int), 1, fp);

//зашифрованный текст

fwrite(A->GetCodedText(), sizeof(char), codedtextlen, fp);

fclose(fp);

}

}

//---------------------------------------------------------------------------

//дешифрование по матрице

void __fastcall TForm1::btnDecryptMClick(TObject *Sender)

{

A->SetKeyM(edtKeyM->Text.c_str());

A->SetCodedText(CodedTextM->Text.c_str());

A->DecryptM();

TextM->Text = A->GetText();

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

if(sbtnClear->Enabled) delete A;

}

//---------------------------------------------------------------------------

//показ формы "О программе"

void __fastcall TForm1::N9Click(TObject *Sender)

{

//создание формы

Application->CreateForm(__classid(TForm2),&Form2);

//показ формы

Form2->ShowModal();

//освобождение ресурсов

Form2->Free();

}

//-----------------------------------------------------------------------------

//сохранить текст из окна Memo1 (TextPascal)

AnsiString MyFName = "";

void __fastcall TForm1::N10Click(TObject *Sender)

{

if(MyFName != "")

TextPascal->Lines->SaveToFile(MyFName);

else

if(SaveDialog1->Execute())

{

MyFName = SaveDialog1->FileName;

TextPascal->Lines->SaveToFile(SaveDialog1->FileName);

}

}

//---------------------------------------------------------------------------

//сохранить как

void __fastcall TForm1::N11Click(TObject *Sender)

{

SaveDialog1->FileName = MyFName;

if(SaveDialog1->Execute())

{

MyFName = SaveDialog1->FileName;

TextPascal->Lines->SaveToFile(SaveDialog1->FileName);

}

}

//---------------------------------------------------------------------------

 

15.На рис.4.5 представлена дополнительная форма «О программе». Это пример представления информации о программе и разработчике. Для включения в проект новой пустой формы достаточно выполнить команду Файл/Новый/Форма или нажать соответствующую быструю кнопку. Модулю дополнительной формы дано имя about. На форме размещены: компонент Image1 (страница Дополнительно), три метки Label1,2,3 и кнопка Button1 с надписью ОК для закрытия этой формы. Картинка помещена на компонент Image1 через его свойство Picture из файла cbuilder в папке …Program Files\Common Files\Borland Shared\Images\Default. Для метки Label1 свойству WordWrap присвоено значение true, чтобы получить возможность переноса слов длинной надписи на новую строчку. Ниже представлены заголовочный файл about.h и файл реализации about.cpp модуля about.

16.Заголовочный файл about.h модуля about

//---------------------------------------------------------------------------

 

#ifndef aboutH

#define aboutH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

#include <Graphics.hpp>

//---------------------------------------------------------------------------

class TForm2 : public TForm

{

__published: // IDE-managed Components

TLabel *Label1;

TLabel *Label2;

TLabel *Label3;

TButton *Button1;

TImage *Image1;

void __fastcall Button1Click(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TForm2(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm2 *Form2;

//---------------------------------------------------------------------------

#endif

17.Файл реализации about.cpp модуля about

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

 

#include "about.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm2 *Form2;

//---------------------------------------------------------------------------

__fastcall TForm2::TForm2(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender)

{

Close();

}

//---------------------------------------------------------------------------

Тестирование и использование приложения

1.Запустите приложение на выполнение, нажав быстрые кнопки Сохранить все и Запуск. Щелкните на кнопке ОК формы «О программе». На главной форме подраздел меню Очистка полей, дублирующая его кнопка инструментальной панели и кнопки Шифрование, Дешифрование окажутся недоступными.

2. В окне TextPascal (Memo1)наберите исходный текст (см. рис.4.6). Щелчком правой кнопкой мыши на окне вызовите всплывающее меню и командой сохранить или сохранить как выведите исходный текст в текстовый файл. Командой Файл/Открыть исходный текст выведите исходный текст в остальные окна исходного текста. Команда главного меню Операции/Инициализация или щелчок на дублирующей ее кнопке инструментальной панели инициализация сделают доступными команду Операции\Очистка полей, кнопку инструментальной панели очистка полей и кнопки Шифрование, Дешифрование, и недоступными команду Операции/Инициализация и кнопку инициализация.

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

4. Дешифровать зашифрованные тексты. Для этого, поочередно стирая исходный текст, щелкайте на кнопках Дешифрование.

5. Вывести на экран зашифрованные тексты. Для этого, стерев зашифрованные тексты, вводите команду Файл\Открыть шифрованный текст и указывайте имена файлов. Убедитесь в правильности операций, повторив п.4. На этом тестирование приложения завершается.

6. Введите команду Операции/Очистка полей или щелкните на кнопке очистка полей. Зашифруйте и дешифруйте произвольные тексты, большие в 3-4 раза тестируемого текста.

7. Командой Файл/Выход или щелчком на кнопке выход завершите выполнение приложения.

 

Контрольные вопросы

1.Как шифровать текст по треугольнику Паскаля, методом Гронсфельда, по матрице? Приведите блок-схемы алгоритмов.

2.Как шифровать слово по треугольнику Паскаля, методом Гронсфельда, по матрице? Приведите блок-схемы алгоритмов.

3.Как шифровать букву по треугольнику Паскаля, методом Гронсфельда, по матрице? Приведите блок-схемы алгоритмов.

4.Как выводятся в файл результаты шифрования?

5.Как дешифровать находящийся в файле зашифрованный текст?

6.Какие возможности дает использование в проекте модулей без форм? Как создать такой модуль? Что он содержит?

7.Объясните содержание класса Codec по его объявлению.

8.Как выполняется директива условной компиляции?

9.Расскажите о реализации класса Codec. С какой целью реализация класса отделяется от его объявления?

10.Как выполняется конструктор класса?

11.Как выполняется деструктор класса?

12.Укажите в коде точки, где вызывается конструктор класса.

13.Где и как нужно изменить код, чтобы вывести количество вызовов конструктора?

14.Укажите в коде точки, где вызывается деструктор класса.

15.Где и как нужно изменить код, чтобы вывести количество вызовов деструктора?

16.Как в приложении дать сведения о приложении и его разработчике? Приведите примеры.

17.Как осуществляется в проекте связь между модулями?

18.Расскажите о порядке проектирования инструментальной панели. Как связать панель с меню?

19.Какие возможности предоставляет пользователю Исследователь Классов?

20.Расскажите о возможных вариантах интерфейса для данного задания.

 


ЛАБОРАТОРНАЯ РАБОТА 5



<== предыдущая лекция | следующая лекция ==>
Файл реализации | ПРЕОБРАЗОВАНИЕ И ВЫЧИСЛЕНИЕ АРИФМЕТИЧЕСКИХ ВЫРАЖЕНИЙ С ПОМОЩЬЮ СТЕКА


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 2.459 сек.