
МСЗИ_23_ИСТ_1_1_Какушкина_Ольга_Витальевна_ЛР_1
.docxМИНОБРНАУКИ РОССИИ
Ф
едеральное
государственное бюджетное образовательное
учреждение высшего образования
НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ
УНИВЕРСИТЕТ им. Р.Е.АЛЕКСЕЕВА
Институт радиоэлектроники и информационных технологий
Кафедра информатики и систем управления
ОТЧЕТ по лабораторной работе №1
(наименование темы проекта или работы)
по дисциплине
Методы и средства защиты информации
(наименование дисциплины)
РУКОВОДИТЕЛЬ:
________________ Жуков М. С.
(подпись) (фамилия, и.,о.)
СТУДЕНТ:
________________ Какушкина О. В.
(подпись) (фамилия, и.,о.)
23-ИСТ-1-1
(шифр группы)
Работа защищена «___» ____________
С оценкой ________________________
Нижний Новгород 2025
Текст задания №1.3:
Реализовать алгоритм шифрования данных «Шифр "двойной квадрат" Уитстона».
Описание алгоритма (Система шифрования "Двойной квадрат Уитстона"):
Алгоритм шифрования "Двойной квадрат Уитстона" является методом ручного шифрования, который использует две таблицы (квадрата) 5x5, заполненные буквами алфавита. Этот метод обеспечивает простоту использования и достаточно высокую стойкость к ручному криптоанализу.
Шаги алгоритма
Подготовка таблиц:
Создаются две таблицы (квадрата) размером 5x5. Каждая таблица заполняется буквами алфавита (обычно исключается буква "J", которая объединяется с "I"). Буквы в таблицах располагаются случайным образом или на основе ключевых слов.
Подготовка исходного сообщения:
Перед шифрованием исходное сообщение разбивают на биграммы.
Шифрование биграмм:
Для каждой биграммы: Первую букву биграммы находят в левой таблице. Вторую букву биграммы находят в правой таблице. Мысленно строят прямоугольник так, чтобы буквы биграммы лежали в его противоположных вершинах. Другие две вершины этого прямоугольника дают буквы биграммы шифртекста.
Формирование шифртекста:
Шифртекст формируется путем объединения всех зашифрованных биграмм.
Рисунок 1 - Пример таблиц для шифрования "Двойной квадрат Уитстона".
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
// Функция для создания квадрата 5x5
vector<vector<char>> createSquare(const string& key) {
vector<vector<char>> square(5, vector<char>(5));
string usedChars; // строка для отслеживания добавленных символов
int row = 0, col = 0;
for (char ch : key) {
if (usedChars.find(toupper(ch)) == string::npos) { // если символ не был добавлен
square[row][col] = toupper(ch);
usedChars += toupper(ch); // сохраняем верхний регистр
col++;
if (col == 5) { // если заполнили строку переходим к следующей
col = 0;
row++;
}
}
}
// прохоим по всем буквам англ алфавита
for (char ch = 'A'; ch <= 'Z'; ch++) {
if (ch == 'J') continue; // Пропускаем 'J', так как она объединена с 'I'
if (usedChars.find(ch) == string::npos) {
square[row][col] = ch;
col++;
if (col == 5) {
col = 0;
row++;
}
}
}
return square;
}
// Функция для отображения двух квадратов на одном уровне
void displaySquares(const vector<vector<char>>& square1, const vector<vector<char>>& square2) {
cout << "Left Square (Square 1) Right Square (Square 2)" << endl;
for (int i = 0; i < 5; i++) {
// Левый квадрат
for (int j = 0; j < 5; j++) {
cout << square1[i][j] << " ";
}
cout << " "; // Разделитель между квадратами
// Правый квадрат
for (int j = 0; j < 5; j++) {
cout << square2[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
// Функция для поиска позиции символа в квадрате
pair<int, int> findPosition(const vector<vector<char>>& square, char ch) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (square[i][j] == toupper(ch)) { // если нашли искомый символ возвращаем его позицию
return { i, j };
}
}
}
return { -1, -1 };
}
// Функция для шифрования пары символов
string encryptPair(const vector<vector<char>>& square1, const vector<vector<char>>& square2, char a, char b) {
// Поиск позиций символов
auto posA = findPosition(square1, a); // находим позицию символа a в левом квадрате
auto posB = findPosition(square2, b); // находим позицию символа b в правом квадрате
// если символ не найден, возвращаем пустую строку
if (posA.first == -1 || posB.first == -1) {
return "";
}
char encryptedA = square2[posA.first][posB.second]; // берем символ из правого квадрата на пересечении строки символа a и столбца символа b
char encryptedB = square1[posB.first][posA.second]; // берем символ из левого квадрата на пересечении строки символа b и столбца символа a
return string(1, encryptedA) + string(1, encryptedB); // возврат зашифр пары
}
// Функция для шифрования текста
string encrypt(const string& text, const string& key1, const string& key2) {
// создание двух квадратов с буквами на основе ключей
vector<vector<char>> square1 = createSquare(key1);
vector<vector<char>> square2 = createSquare(key2);
// Отображаем квадраты
displaySquares(square1, square2);
string encryptedText;
for (size_t i = 0; i < text.length(); i += 2) { // разбиваем текст на биграммы
char a = text[i];
char b = (i + 1 < text.length()) ? text[i + 1] : 'X'; // Добавляем 'X', если не хватает символа
encryptedText += encryptPair(square1, square2, a, b); // добавляем в зашифр текст новую зашифр пару
}
return encryptedText;
}
// Функция для расшифрования пары символов
string decryptPair(const vector<vector<char>>& square1, const vector<vector<char>>& square2, char a, char b) {
auto posA = findPosition(square2, a); // находим позицию а в правом квадрате
auto posB = findPosition(square1, b); // находим позицию b в левом квадрате
// если символ не найден, возвращаем пустую строку
if (posA.first == -1 || posB.first == -1) {
return "";
}
char decryptedA = square1[posA.first][posB.second]; // берем символ из левого квадрата на пересечении строки символа a и столбца символа b
char decryptedB = square2[posB.first][posA.second]; // берем символ из правого квадрата на пересечении строки символа b и столбца символа a
return string(1, decryptedA) + string(1, decryptedB);
}
// Функция для расшифрования текста
string decrypt(const string& text, const string& key1, const string& key2) {
vector<vector<char>> square1 = createSquare(key1);
vector<vector<char>> square2 = createSquare(key2);
// Отображаем квадраты
displaySquares(square1, square2);
string decryptedText;
for (size_t i = 0; i < text.length(); i += 2) {
char a = text[i];
char b = (i + 1 < text.length()) ? text[i + 1] : 'X'; // Добавляем 'X', если не хватает символа
decryptedText += decryptPair(square1, square2, a, b); // расшифровываем пару и длобавляем к итоговой строке
}
// Удаляем символ-заполнитель 'X', если он был добавлен
if (!decryptedText.empty() && decryptedText.back() == 'X') {
decryptedText.pop_back();
}
return decryptedText;
}
int main() {
int choice;
string text, key1, key2;
while (true) {
cout << "Choose an option:" << endl;
cout << "1. Encrypt" << endl;
cout << "2. Decrypt" << endl;
cout << "3. Exit" << endl;
cout << "Enter your choice: ";
cin >> choice;
if (choice == 3) {
break;
}
cout << "Enter the text: ";
cin >> text;
cout << "Enter the first key: ";
cin >> key1;
cout << "Enter the second key: ";
cin >> key2;
if (choice == 1) {
string encryptedText = encrypt(text, key1, key2);
cout << "Encrypted text: " << encryptedText << endl;
}
else if (choice == 2) {
string decryptedText = decrypt(text, key1, key2);
cout << "Decrypted text: " << decryptedText << endl;
}
else {
cout << "Invalid choice. Please try again." << endl;
}
cout << endl;
}
return 0;
}
Вывод программы
Рисунок 2 - Результат работы программы .
Рисунок 3 - Результат работы программы для примера 2.
Вывод:
В ходе лабораторной работы я работала с алгоритмом двойной квадрат Уитстона. Научилась шифровать и расшифровывать текст данным методом.