-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMatrixEncryptor.cpp
100 lines (88 loc) · 3.22 KB
/
MatrixEncryptor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "MatrixEncryptor.h"
#include <random>
#include <iostream>
#include <sstream>
namespace {
inline void removeLastASCIISpaces(std::vector<int>& data) {
while (!data.empty() && data.back() == ' ') {
data.pop_back();
}
}
}
Eigen::MatrixXd MatrixEncryptor::generateRandomKey(int size) {
Eigen::MatrixXd key(size, size);
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_real_distribution<double> distribution(-10.0, 10.0);
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
key(i, j) = distribution(generator);
}
}
return key;
}
MatrixEncryptor::MatrixEncryptor(int size) {
keyMatrix = generateRandomKey(size);
}
MatrixEncryptor::MatrixEncryptor(const Eigen::MatrixXd& customKey) : keyMatrix(customKey) {}
std::vector<int> MatrixEncryptor::encrypt(const std::vector<int>& message) const {
int size = keyMatrix.rows();
int messageSize = message.size();
int remainder = size - (messageSize % size);
std::vector<int> paddedMessage = message;
paddedMessage.insert(paddedMessage.end(), remainder, ' '); // Padding message with spaces to make its size a multiple of the key matrix size
std::vector<int> encrypted_message;
for (size_t i = 0; i < paddedMessage.size(); i += size) {
Eigen::VectorXd messageVector(size);
for (int j = 0; j < size; ++j) {
messageVector(j) = paddedMessage[i + j];
}
Eigen::VectorXd encryptedVector = keyMatrix * messageVector;
for (int j = 0; j < size; ++j) {
encrypted_message.push_back(static_cast<int>(std::round(encryptedVector(j))));
}
}
return encrypted_message;
}
std::vector<int> MatrixEncryptor::decrypt(const std::vector<int>& encrypted_message, int size) const {
std::vector<int> decrypted_message;
for (size_t i = 0; i < encrypted_message.size(); i += size) {
Eigen::VectorXd encryptedVector(size);
for (int j = 0; j < size; ++j) {
encryptedVector(j) = encrypted_message[i + j];
}
Eigen::MatrixXd inverseKey = keyMatrix.inverse();
Eigen::VectorXd decryptedVector = inverseKey * encryptedVector;
for (int j = 0; j < size; ++j) {
// Round to the nearest integer before converting back to int
int decrypted_value = static_cast<int>(std::round(decryptedVector(j)));
decrypted_message.push_back(decrypted_value);
}
}
removeLastASCIISpaces(decrypted_message);
return decrypted_message;
}
const Eigen::MatrixXd& MatrixEncryptor::getKey() const {
return keyMatrix;
}
std::vector<int> MatrixEncryptor::parseInput(const std::string& input) {
std::vector<int> parsed;
std::istringstream iss(input);
std::string token;
while (iss >> token) {
for (char c : token) {
parsed.push_back(static_cast<int>(c));
}
parsed.push_back(' '); // Add space after each token
}
return parsed;
}
Eigen::MatrixXd MatrixEncryptor::getCustomKey(int size) {
Eigen::MatrixXd customKey(size, size);
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
std::cin >> customKey(i, j);
}
}
return customKey;
}