
Лаб. 2 ЗИ
.docxЗащита информации. Лабораторная работа №2
#include <iostream>
#include <fstream>
#include <vector>
#include <random>
#include <unordered_map>
#include <set>
#include <string>
#include <chrono>
#include <numeric>
#include<map>
using namespace std;
int GeneratePrimeNumber(mt19937& gen, uniform_int_distribution<int>& dist) {
int number;
bool flag;
//srand(time(NULL));
do {
flag = true;
number = dist(gen);
for (int i = 2; i <= sqrt(number); i++) {
if (number % i == 0) {
flag = false;
}
}
} while (!flag);
return number;
}
int GenerateMutuallyPrimeNumber(int euler_function,mt19937& gen, uniform_int_distribution<int>& dist_e) {
//int e;
int e = 2;
int temp_e;
int gcd;
int temp_ef;
//do {
// //e = dist_e(gen);
// temp_e = e;
// if (temp_e > euler_function) {
// while (temp_ef != 0) {
// int temp = temp_ef;
// temp_ef = temp_e % temp_ef;
// temp_e = temp;
// }
// cout << "^1" << endl;
// gcd = temp_e;
// }
// else if (temp_e < euler_function) {
// while (temp_e != 0) {
// int temp = temp_e;
// cout << "temp: " << temp << endl;
// temp_e = temp_ef % temp_e;
// cout << "temp_e: " << temp_e << endl;
// temp_ef = temp;
// cout << "temp_ef: " << temp_ef << endl;
// }
// cout << "^2" << endl;
// gcd = temp_ef;
// }
// e++;
//} while (gcd != 1);
do {
e = dist_e(gen);
temp_e = e;
temp_ef = euler_function;
while (temp_ef != 0) {
int temp = temp_ef;
//cout << "temp: " << temp << endl;
temp_ef = temp_e % temp_ef;
//cout << "temp_ef: " << temp_ef << endl;
temp_e = temp;
//cout << "temp_e: " << temp_e << endl;
}
//cout << endl;
gcd = temp_e;
//e++;
}while (gcd != 1);
//e--;
return e;
}
long long ModExp(long long base, long long exp, long long mod) {
long long result = 1;
base = base % mod;
while (exp > 0) {
if (exp % 2 == 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
exp /= 2;
}
return result;
}
void RsaEncryptAndDecrypt(string file_fullname, string file_extension) {
ifstream reading_file(file_fullname, ios::binary);
if (!reading_file) {
cout << "Ошибка открытия файла!" << endl;
return;
}
char byte;
set<unsigned char> bytes;
while (reading_file.get(byte)) {
bytes.insert(static_cast<unsigned char>(byte));
}
reading_file.close();
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<int> dist_pq(256, 1000);
int p = GeneratePrimeNumber(gen, dist_pq);
int q = GeneratePrimeNumber(gen, dist_pq);
cout << "p: " << p << endl;
cout << "q: " << q << endl;
int n = p * q;
int euler_function = (p - 1) * (q - 1);
uniform_int_distribution<int> dist_e(2, n - 1);
cout << "n: " << n << endl;
cout << "euler_function: " << euler_function << endl;
int e = GenerateMutuallyPrimeNumber(euler_function, gen, dist_e);
//cout << euler_function << endl;
cout << "e: " << e << endl;
double d;
int k = 1;
do {
d = (k * static_cast<double>(euler_function) + 1.0) / static_cast<double>(e);
//cout << d << endl;
k++;
} while (floor(d) != d);
//cout << endl;
//cout << k << endl;
cout << "d: " << d << endl;
d = static_cast<int>(d);
int c_i;
map<unsigned char, long long> code;
for (unsigned char byte : bytes) {
//int byte_int = static_cast<int>(byte);
//c_i = static_cast<long long>(pow(byte, e)) % n;
c_i = ModExp(byte, e, n);
code[byte] = c_i;
}
cout << endl;
for (const pair<unsigned char, long long>& item : code) {
cout << "Код: " << static_cast<int>(item.first) << " -> Новый код: " << item.second << endl;
}
//string encrypt_file_name = "lab2_encrypt";
//string encrypt_file_fullname = encrypt_file_name + file_extension;
string encrypt_file_fullname = "lab2_encrypt.txt";
ifstream reading_file2(file_fullname, ios::binary);
//ofstream writing_encrypt_file(encrypt_file_fullname, ios::binary);
ofstream writing_encrypt_file(encrypt_file_fullname);
if (!reading_file2 || !writing_encrypt_file) {
cout << "Ошибка открытия файла для шифрования!" << endl;
return;
}
/* cout << endl;
cout << "1:" << endl;
for (const pair<unsigned char, long long>& item : code) {
cout << item.first << ": " << item.second << endl;
}
cout << endl;*/
while (reading_file2.get(byte)) {
//writing_encrypt_file.put(code[byte]);
writing_encrypt_file << code[static_cast<unsigned char>(byte)] << " ";
}
/*cout << endl;
cout << "2:" << endl;
for (const pair<unsigned char, long long>& item : code) {
cout << item.first << ": " << item.second << endl;
}
cout << endl;*/
reading_file2.close();
writing_encrypt_file.close();
map<long long, int> decode;
int t_i;
//cout << endl;
//cout << "3:" << endl;
for (const pair<unsigned char, long long>& item : code) {
//t_i = static_cast<long long>(pow(item.second, d)) % n;
//cout << item.first << ": " << item.second << endl;
t_i = ModExp(item.second, d, n);
decode[item.second] = t_i;
}
//cout << endl;
cout << endl;
for (const pair<long long, int>& item : decode) {
cout << "Новый код: " << item.first << " -> Старый код: " << item.second << endl;
}
string decrypt_file_name = "lab2_decrypt";
string decrypt_file_fullname = decrypt_file_name + file_extension;
//string decrypt_file_fullname = "lab2_decrypt.txt";
//ifstream reading_encrypt_file(encrypt_file_fullname, ios::binary);
ifstream reading_encrypt_file(encrypt_file_fullname);
ofstream writing_decrypt_file(decrypt_file_fullname, ios::binary);
if (!reading_encrypt_file || !writing_decrypt_file) {
cout << "Ошибка открытия файла для дешифрования!" << endl;
return;
}
/*while (reading_encrypt_file.get(byte)) {
writing_decrypt_file.put(decode[byte]);
}*/
int number;
while (reading_encrypt_file >> number) {
writing_decrypt_file.put(decode[number]);
}
reading_encrypt_file.close();
writing_decrypt_file.close();
// сравнение файлов
ifstream original_file(file_fullname, ios::binary);
ifstream decode_file(decrypt_file_fullname, ios::binary);
bool filesMatch = true;
char originalByte, recoveredByte;
while (true) {
bool originalRead = original_file.get(originalByte).good();
bool recoveredRead = decode_file.get(recoveredByte).good();
if (originalRead != recoveredRead) {
filesMatch = false; // один файл закончился, а другой нет
break;
}
if (!originalRead) break; // оба файла закончились
if (originalByte != recoveredByte) {
filesMatch = false;
break;
}
}
original_file.close();
decode_file.close();
cout << endl;
if (filesMatch) {
cout << "Исходный файл равен восстановленному." << endl;
}
else {
cout << "Исходный файл НЕ равен восстановленному." << endl;
}
}
int main() {
setlocale(LC_ALL, "Rus");
string file_name = "lab2_source";
string file_extension = ".txt";
//string file_extension = ".flac";
string file_fullname = file_name + file_extension;
RsaEncryptAndDecrypt(file_fullname, file_extension);
return 0;
}