密码1:凯撒密码
#include <iostream>
#include <vector>
#include <string>
#include <sstream> // 用于分割字符串
using namespace std;
//输入
void InputName(vector<string>& name, string input) {
std::cout << "请输入你的字母串(按回车键结束):\n";
std::getline(std::cin, input); // 获取整行输入
std::stringstream ss(input); // 使用 stringstream 分割字符串
std::string word;
while (ss >> word) {
name.push_back(word); // 将每个单词加入 vector
}
return;
}
//输出
void output(vector<string>& name) {
for (int i = 0; i < name.size(); i++) {
cout << name[i] << endl;
}
return;
}
//加密函数
vector<string> Encryption(vector<string>& name) {
std::vector<std::string> ciphertext; // 存储加密后的结果
for (int i = 0; i < name.size(); i++) {
std::string encrypted_str = ""; // 存储单个字符串的加密结果
for (char ch : name[i]) {
if (isalpha(ch)) {
// 处理大小写字母
char base = islower(ch) ? 'a' : 'A';
encrypted_str += (ch - base + 3) % 26 + base;
}
else {
encrypted_str += ch; // 非字母字符保持不变
}
}
ciphertext.push_back(encrypted_str); // 将加密后的字符串放入结果
}
return ciphertext; // 返回加密结果
}
//解密函数
vector<string> Decode(vector<string>& name) {
std::vector<std::string> proclaim; // 存储加密后的结果
for (int i = 0; i < name.size(); i++) {
std::string proclaim_str = ""; // 存储单个字符串的加密结果
for (char ch : name[i]) {
if (isalpha(ch)) {
// 处理大小写字母
char base = islower(ch) ? 'a' : 'A';
proclaim_str += (ch - base - 3 + 26) % 26 + base;
}
else {
proclaim_str += ch; // 非字母字符保持不变
}
}
proclaim.push_back(proclaim_str); // 将加密后的字符串放入结果
}
return proclaim; // 返回加密结果
}
int main() {
string input;
int judge;
cout << "密码名称:凯撒密码" << endl;
while (1) {
vector<string>name;
cout << "输入1选择加密功能,输入2选择解密功能,输入其它任意数字结束程序" << endl;
cin >> judge;
if (judge != 1 && judge != 2) {
break;
}
std::getline(std::cin, input); // 获取整行输入
if (judge == 1) {
vector<string> ciphertext;
InputName(name, input);
ciphertext = Encryption(name);
cout << "加密结果为:" << endl;
output(ciphertext);
}
if (judge == 2) {
vector<string> proclaim;
InputName(name, input);
proclaim = Decode(name);
cout << "解密结果为:" << endl;
output(proclaim);
}
}
return 0;
}
密码2:仿射密码
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
//输入
void InputName(vector<string>& name, string input) {
std::cout << "请输入你的字母串(按回车键结束):\n";
std::getline(std::cin, input); // 获取整行输入
std::stringstream ss(input); // 使用 stringstream 分割字符串
std::string word;
while (ss >> word) {
name.push_back(word); // 将每个单词加入 vector
}
return;
}
//输出
void output(vector<string>& name) {
for (int i = 0; i < name.size(); i++) {
cout << name[i] << endl;
}
return;
}
//加密函数
vector<string> Encryption(vector<string>& name,int a,int b) {
std::vector<std::string> ciphertext; // 存储加密后的结果
for (int i = 0; i < name.size(); i++) {
std::string encrypted_str = ""; // 存储单个字符串的加密结果
for (char ch : name[i]) {
if (isalpha(ch)) {
// 处理大小写字母
char base = islower(ch) ? 'a' : 'A';
encrypted_str += (a * (ch - base) + b) % 26 + base;
}
else {
encrypted_str += ch; // 非字母字符保持不变
}
}
ciphertext.push_back(encrypted_str); // 将加密后的字符串放入结果
}
return ciphertext; // 返回加密结果
}
// 计算 a 的模 26 下的乘法逆元
int modInverse(int a, int m) {
a = a % m;
for (int x = 1; x < m; x++) {
if ((a * x) % m == 1) {
return x;
}
}
throw std::invalid_argument("没有乘法逆元,a 和 26 不是互质");
}
//解密
std::vector<std::string> Decode(std::vector<std::string>& name, int a, int b) {
std::vector<std::string> proclaim; // 存储解密后的结果
// 计算 a 在模 26 下的逆元
int a_inv = modInverse(a, 26);
for (int i = 0; i < name.size(); i++) {
std::string proclaim_str = ""; // 存储单个字符串的解密结果
for (char ch : name[i]) {
if (isalpha(ch)) {
char base = islower(ch) ? 'a' : 'A'; // 判断大小写字母
// 解密公式:D(x) = a_inv * (x - b) % 26
proclaim_str += (a_inv * ((ch - base - b + 26) % 26)) % 26 + base;
}
else {
proclaim_str += ch; // 非字母字符保持不变
}
}
proclaim.push_back(proclaim_str); // 将解密后的字符串放入结果
}
return proclaim; // 返回解密结果
}
int main() {
string input;
int judge;
int a, b;
cout << "密码名称:仿射密码" << endl;
while (1) {
cout << "输入密钥a b" << endl;
cin >> a >> b;
vector<string>name;
cout << "输入1选择加密功能,输入2选择解密功能,输入其它任意数字结束程序" << endl;
cin >> judge;
if (judge != 1 && judge != 2) {
break;
}
std::getline(std::cin, input); // 获取整行输入
if (judge == 1) {
vector<string> ciphertext;
InputName(name, input);
ciphertext = Encryption(name,a,b);
cout << "加密结果为:" << endl;
output(ciphertext);
}
if (judge == 2) {
vector<string> proclaim;
InputName(name, input);
proclaim = Decode(name,a,b);
cout << "解密结果为:" << endl;
output(proclaim);
}
}
}
密码3:维吉尼亚密码
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
//输入
void InputName(vector<string>& name, string input) {
std::cout << "请输入你的字符串(按下回车键结束)" << endl;
std::getline(std::cin, input); //获取整行输入
std::stringstream ss(input); //使用stringstream 分割字符串
std::string word;
while (ss >> word) {
name.push_back(word);
}
return;
}
//输出
void output(vector<string>& name) {
for (int i = 0; i < name.size(); i++) {
cout << name[i] << " ";
}
cout << endl;
return;
}
//输入密钥
void InputKey(vector<int>& key) {
int k;
cout << "请输入密钥key的长度k" << endl;
cin >> k;
cout << "请输入密钥k,其中包含" << k << "个数字" << endl;
for (int i = 0; i < k; i++) {
int m;
cin >> m;
key.push_back(m);
}
return;
}
//加密函数
vector<string> Encryption(vector<string>& name,vector<int> &key) {
std::vector<std::string> ciphertext; //存储加密后的结果
int j = 0;
for (int i = 0; i < name.size(); i++) {
std::string encrypted_str = ""; //存储单个字符串的加密结果
for (char ch : name[i]) {
if (j >= key.size()) {
j = 0;
}
if (isalpha(ch)) {
//处理大小写字母
char base = islower(ch) ? 'a' : 'A';
encrypted_str += (ch - base + key[j]) % 26 + base;
j++;
}
else {
encrypted_str += ch;
}
}
ciphertext.push_back(encrypted_str);//加密后的字符串存入
}
return ciphertext;
}
//解密函数
vector<string> Decode(vector<string>& name, vector<int>& key) {
std::vector<std::string> proclaim; //存储加密后的结果
int j = 0;
for (int i = 0; i < name.size(); i++) {
std::string proclaim_str = ""; //存储单个字符串的解密结果
for (char ch : name[i]) {
if (j >= key.size()) {
j = 0;
}
if (isalpha(ch)) {
//处理大小写字母
char base = islower(ch) ? 'a' : 'A';
proclaim_str += (ch - base - key[j]) % 26 + base;
j++;
}
else {
proclaim_str += ch;
}
}
proclaim.push_back(proclaim_str);//解密后的字符串存入
}
return proclaim;
}
int main() {
cout << "密码名称:维吉尼亚密码" << endl;
while (1) {
vector<string> ciphertext;
vector<string> proclaim;
string input;
vector<string>name;
vector<int> key;
int num = 0;
int judge;
cout << "输入1选择加密功能,输入2选择解密功能,输入其它任意数字结束程序" << endl;
cin >> judge;
if (judge != 1 && judge != 2) {
break;
}
std::getline(std::cin, input); //获取整行输入
if (judge == 1) {
InputName(name, input);
for (int i = 0; i < name.size(); i++) {
num += name[i].size();
}
InputKey(key);
ciphertext = Encryption(name, key);
cout << "加密结果为:" << endl;
output(ciphertext);
}
if (judge == 2) {
InputName(name, input);
for (int i = 0; i < name.size(); i++) {
num += name[i].size();
}
InputKey(key);
proclaim = Decode(name, key);
cout << "解密结果为:" << endl;
output(proclaim);
}
}
return 0;
}
密码4:希尔密码
//1.输入密文
//2.将密文中的字母转化为数字
//3.将数字映射入二维矩阵(列可以自定义)
//4.输入加密矩阵
//5.两个矩阵进行乘法
//6.输出加密矩阵
//7.将加密矩阵中的数字转化为密文
//注:此密码不区分大小写,输出加密结果统一为小写
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <stdexcept>
#include <iomanip> // 用于设置输出格式
using namespace std;
//输入
void InputName(vector<string>& name, string input) {
std::cout << "请输入你的字母串(按回车键结束):\n";
std::getline(std::cin, input); // 获取整行输入
std::stringstream ss(input); // 使用 stringstream 分割字符串
std::string word;
while (ss >> word) {
name.push_back(word); // 将每个单词加入 vector
}
return;
}
//输出
void output(vector<string>& name) {
for (int i = 0; i < name.size(); i++) {
cout << name[i] ;
}
cout << endl;
return;
}
//输入矩阵
std::vector<std::vector<int>> Input_matrix(int cols, int rows) {
//初始化加密矩阵
vector<vector<int>> matrix(rows, vector<int>(cols, 0));
cout << "请输入" << rows << "行" << cols << "列" << "的二维矩阵" << endl;
// 读取用户输入的矩阵数据
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
cin >> matrix[i][j];
}
}
return matrix; // 返回用户输入的矩阵
}
// 打印int型矩阵
void printMatrix(const std::vector<std::vector<int>>& matrix) {
// 遍历二维数组的每一行
for (const auto& row : matrix) {
// 遍历每行中的每个元素
for (const auto& element : row) {
std::cout << setw(6) << setprecision(2) << element << " "; // 输出元素并在同一行中添加空格
}
std::cout << std::endl; // 每一行输出完毕后换行
}
}
// 打印double型矩阵
void printMatrix2(const vector<vector<double>>& matrix) {
for (const auto& row : matrix) {
for (const auto& element : row) {
cout << setw(6) << setprecision(2) << element << " ";
}
cout << endl;
}
}
//将 vector<string> 容器中的字符转化为对应的数字编码
std::vector<std::vector<int>> convertToFigure(const std::vector<std::string>& name) {
std::vector<std::vector<int>> result; // 用于存储每个字符串中字符的数字编码
// 遍历每个字符串
for (const auto& str : name) {
std::vector<int> Codes; // 用于存储单个字符串中每个字符的 数字编码
// 遍历字符串中的每个字符
for (const auto& ch : str) {
if (isalpha(ch)) {
// 处理大小写字母
char base = islower(ch) ? 'a' : 'A';
Codes.push_back(static_cast<int>(ch - base) ); // 将字符转为 数字编码并存储
}
}
result.push_back(Codes); // 将该字符串的数字编码列表加入结果向量
}
return result; // 返回所有字符串的数字编码结果
}
//将数字编码转化为字符并存入 vector<string> 容器
std::vector<std::string> convertToStrings(const std::vector<std::vector<int>>& Codes) {
std::vector<std::string> result; // 存储转换后的字符串
// 遍历每个数字编码的向量
for (const auto& eachCodes : Codes) {
std::string str; // 用于存储单个字符串
// 将每个数字编码转为对应的字符,并添加到字符串中
for (const auto& code : eachCodes) {
char base = 'a';
str += static_cast<char>(code + base ); // 将数字编码转换为字符
}
result.push_back(str); // 将转换后的字符串加入结果向量
}
return result; // 返回存储了字符串的向量
}
// 根据用户自定义的列数,将 vector<int> 中的数据存储进二维数组
std::vector<std::vector<int>> convertToMatrix(const std::vector<std::vector<int>>& Codes, int cols, int rows) {
//计数器
int count = 0;
vector<int> codes; //将Codes中的数字编码存入vector<int>型容器中
//初始矩阵
std::vector<std::vector<int>> Initial_matrix(rows, std::vector<int>(cols, 0));
//类型转换
for (const auto& eachcodes : Codes) {
for (const auto& code : eachcodes) {
codes.push_back(code); // 将 Codes 中的所有元素存入 codes
}
}
// 按行优先填充矩阵
for (int i = 0; i < rows; ++i) { // 遍历每一行
for (int j = 0; j < cols; ++j) { // 遍历每一列
if (count < codes.size()) { // 确保 count 不越界
Initial_matrix[i][j] = codes[count];
count++;
}
else {
// 如果 codes 数据不足以填满矩阵,可以选择填充默认值(如 0)
Initial_matrix[i][j] = 0;
}
}
}
return Initial_matrix; // 返回二维数组
}
//计算矩阵的行数
int Count_rows(int cols, int num) {
int rows;
if (num % cols == 0) {
rows = num / cols;
}
else {
rows = num / cols + 1;
}
return rows;
}
//计算密码的位数
int Count(const std::vector<string>& name) {
int num = 0;
for (const auto& str : name) {
// 遍历字符串中的每个字符
for (const auto& ch : str) {
num++;
}
}
return num;
}
// 进行矩阵乘法,输入的两个矩阵数据类型均为int型,返回相乘后的矩阵int型
std::vector<std::vector<int>> multiplyMatrices(const std::vector<std::vector<int>>& A, const std::vector<std::vector<int>>& B) {
int rowsA = A.size();
int colsA = A[0].size();
int colsB = B[0].size();
// 初始化结果矩阵 C,大小为 rowsA x colsB
std::vector<std::vector<int>> C(rowsA, std::vector<int>(colsB, 0));
// 矩阵乘法计算
for (int i = 0; i < rowsA; ++i) {
for (int j = 0; j < colsB; ++j) {
for (int k = 0; k < colsA; ++k) {
C[i][j] += (A[i][k] * B[k][j]);
}
C[i][j] = C[i][j] % 26 ;
}
}
return C;
}
// 进行矩阵乘法,输入的两个矩阵数据类型第一个为int型,第二个为double型,返回相乘后的矩阵double型
std::vector<std::vector<double>> multiplyMatrices2(const std::vector<std::vector<int>>& A, const std::vector<std::vector<double>>& B) {
int rowsA = A.size();
int colsA = A[0].size();
int colsB = B[0].size();
// 初始化结果矩阵 C,大小为 rowsA x colsB
std::vector<std::vector<double>> C(rowsA, std::vector<double>(colsB, 0));
// 矩阵乘法计算
for (int i = 0; i < rowsA; ++i) {
for (int j = 0; j < colsB; ++j) {
for (int k = 0; k < colsA; ++k) {
C[i][j] += (A[i][k] * B[k][j]);
}
C[i][j] = fmod(C[i][j], 26.0);
}
}
return C;
}
// 打印分割线
void printSeparator(int length, char character ) {
for (int i = 0; i < length; ++i) {
cout << character;
}
cout << endl;
}
//以下内容为高斯-约旦消元法求矩阵的逆矩阵
// 交换矩阵的两行
void swapRows(vector<vector<double>>& matrix, int row1, int row2) {
swap(matrix[row1], matrix[row2]);
}
// 对矩阵进行高斯-约旦消元法处理
vector<vector<double>> invertMatrix(const vector<vector<int>>& matrix) {
int n = matrix.size();
vector<vector<double>> A(n, vector<double>(n));
vector<vector<double>> I(n, vector<double>(n, 0.0));
// 初始化单位矩阵
for (int i = 0; i < n; ++i) {
I[i][i] = 1.0;
}
// 将整数矩阵转换为浮点型矩阵进行计算
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
A[i][j] = static_cast<double>(matrix[i][j]);
}
}
// 高斯-约旦消元法
for (int i = 0; i < n; ++i) {
if (A[i][i] == 0) {
// 寻找非零的主元素并交换行
bool swapped = false;
for (int k = i + 1; k < n; ++k) {
if (A[k][i] != 0) {
swapRows(A, i, k);
swapRows(I, i, k);
swapped = true;
break;
}
}
if (!swapped) {
throw runtime_error("Matrix is singular and cannot be inverted.");
}
}
double pivot = A[i][i];
for (int j = 0; j < n; ++j) {
A[i][j] /= pivot;
I[i][j] /= pivot;
}
for (int j = 0; j < n; ++j) {
if (i != j) {
double factor = A[j][i];
for (int k = 0; k < n; ++k) {
A[j][k] -= factor * A[i][k];
I[j][k] -= factor * I[i][k];
}
}
}
}
return I;
}
int main() {
vector<int> transition;
vector<vector<int>> Codes;
vector<string> result;
vector<string>ciphertext;
vector<vector<int>> Initial_matrix;
vector<vector<int>> Key_matrix;
vector<vector<int>> MultiplyMatrice;
vector<vector<int>> Encryption_matrix;
vector<vector<double>> inverse_matrix;
int judge;
cout << "密码名称:希尔密码" << endl;
while (1) {
int num;
int cols;
int rows;
vector<string> name;
string input;
cout << "输入1选择加密功能,输入2选择解密功能,输入其它任意数字结束程序" << endl;
cin >> judge;
std::getline(std::cin, input); // 获取回车
if (judge == 1) {
cout << "已进入加密功能" << endl;
printSeparator(30, '-');
//输入明文
InputName(name, input);
printSeparator(30, '-');
//计算明文的位数
Codes = convertToFigure(name);
num = Count(name);
cout << "明文位数为:" << num << endl;
printSeparator(30, '-');
//输入明文矩阵列数
cout << "请输入明文矩阵的列数" << endl;
cin >> cols;
cout << "明文矩阵列数为:" << cols << endl;
printSeparator(30, '-');
//计算明文矩阵的行数
rows = Count_rows(cols, num);
cout << "明文矩阵行数为:" << rows << endl;
printSeparator(30, '-');
//将明文数字编码存入二维矩阵中
Initial_matrix = convertToMatrix(Codes, cols, rows);
cout << "初始矩阵为:" << endl;
printMatrix(Initial_matrix);
printSeparator(30, '-');
//输入加密矩阵
int Key_rows = cols;
int Key_cols = cols;
cout << "加密矩阵的行数为:" << Key_rows << "加密矩阵的列数为:" << Key_cols << endl;
Key_matrix = Input_matrix(Key_cols, Key_rows);
cout << "加密矩阵为:" << endl;
printMatrix(Key_matrix);
printSeparator(30, '-');
//矩阵乘法计算并输出
MultiplyMatrice = multiplyMatrices(Initial_matrix, Key_matrix);
cout << "加密后的矩阵为:" << endl;
printMatrix(MultiplyMatrice);
printSeparator(30, '-');
//输出密文
cout << "密文为:" << endl;
ciphertext = convertToStrings(MultiplyMatrice);
output(ciphertext);
}else if (judge == 2) {
cout << "已进入解密功能" << endl;
printSeparator(30, '-');
//输入密文
InputName(name, input);
printSeparator(30, '-');
//计算密文的位数
Codes = convertToFigure(name);
num = Count(name);
cout << "密文位数为:" << num << endl;
printSeparator(30, '-');
//输入加密矩阵
int Key_rows;
int Key_cols;
cout << "加密矩阵的行数和列数(必须相等):" << endl;
cin >> Key_rows;
cin >> Key_cols;
cout << "加密矩阵的行数为:" << Key_rows << "加密矩阵的列数为:" << Key_cols << endl;
Key_matrix = Input_matrix(Key_cols, Key_rows);
cout << "加密矩阵为:" << endl;
printMatrix(Key_matrix);
printSeparator(30, '-');
//密文转化为矩阵
//计算密文的列数
cols = Key_rows;
cout << "密文矩阵的列数为:" << cols << endl;
//计算密文矩阵的行数
rows = Count_rows(cols, num);
cout << "明文矩阵行数为:" << rows << endl;
//将密文数字编码存入二维矩阵中
Encryption_matrix = convertToMatrix(Codes, cols, rows);
cout << "初始矩阵为:" << endl;
printMatrix(Encryption_matrix);
printSeparator(30, '-');
//计算明文矩阵
//1.求加密矩阵的逆
inverse_matrix = invertMatrix(Key_matrix);
cout << "加密矩阵的逆矩阵为:" << endl;
printMatrix2(inverse_matrix);
printSeparator(30, '-');
vector<vector<double>> matrix;
//2.密文与加密矩阵的逆矩阵进行乘法
matrix = multiplyMatrices2(Encryption_matrix, inverse_matrix);
cout << "明文矩阵为:" << endl;
printMatrix2(matrix);
printSeparator(30, '-');
//将明文矩阵还原为明文并输出
cout << "明文为:" << endl;
result = convertToStrings(Initial_matrix);
output(result);
}
else {
break;
}
}
return 0;
}
2.利用行列式和伴随矩阵求矩阵的逆矩阵
//1.输入密文
//2.将密文中的字母转化为数字
//3.将数字映射入二维矩阵(列可以自定义)
//4.输入加密矩阵
//5.两个矩阵进行乘法
//6.输出加密矩阵
//7.将加密矩阵中的数字转化为密文
//注:此密码不区分大小写,输出加密结果统一为小写
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <stdexcept>
#include <iomanip> // 用于设置输出格式
using namespace std;
vector<vector<int>> getCofactor(const vector<vector<int>>& mat, int p, int q, int n);
//输入
void InputName(vector<string>& name, string input) {
std::cout << "请输入你的字母串(按回车键结束):\n";
std::getline(std::cin, input); // 获取整行输入
std::stringstream ss(input); // 使用 stringstream 分割字符串
std::string word;
while (ss >> word) {
name.push_back(word); // 将每个单词加入 vector
}
return;
}
//输出
void output(vector<string>& name, int n) {
int coust = 0;
for (const string& ch : name) {
for (int i = 0; i < ch.size(); i++) {
cout << ch[i];
coust++;
if (coust == n) {
break;
}
}
}
cout << endl;
return;
}
//输入矩阵
std::vector<std::vector<int>> Input_matrix(int cols, int rows) {
//初始化加密矩阵
vector<vector<int>> matrix(rows, vector<int>(cols, 0));
cout << "请输入" << rows << "行" << cols << "列" << "的二维矩阵" << endl;
// 读取用户输入的矩阵数据
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
cin >> matrix[i][j];
}
}
return matrix; // 返回用户输入的矩阵
}
// 打印int型矩阵
void printMatrix(const std::vector<std::vector<int>>& matrix) {
// 遍历二维数组的每一行
for (const auto& row : matrix) {
// 遍历每行中的每个元素
for (const auto& element : row) {
std::cout << setw(6) << setprecision(2) << element << " "; // 输出元素并在同一行中添加空格
}
std::cout << std::endl; // 每一行输出完毕后换行
}
}
//将 vector<string> 容器中的字符转化为对应的数字编码
std::vector<std::vector<int>> convertToFigure(const std::vector<std::string>& name) {
std::vector<std::vector<int>> result; // 用于存储每个字符串中字符的数字编码
// 遍历每个字符串
for (const auto& str : name) {
std::vector<int> Codes; // 用于存储单个字符串中每个字符的 数字编码
// 遍历字符串中的每个字符
for (const auto& ch : str) {
if (isalpha(ch)) {
// 处理大小写字母
char base = islower(ch) ? 'a' : 'A';
Codes.push_back(static_cast<int>(ch - base)); // 将字符转为 数字编码并存储
}
}
result.push_back(Codes); // 将该字符串的数字编码列表加入结果向量
}
return result; // 返回所有字符串的数字编码结果
}
//将数字编码转化为字符并存入 vector<string> 容器
std::vector<std::string> convertToStrings(const std::vector<std::vector<int>>& Codes) {
std::vector<std::string> result; // 存储转换后的字符串
// 遍历每个数字编码的向量
for (const auto& eachCodes : Codes) {
std::string str; // 用于存储单个字符串
// 将每个数字编码转为对应的字符,并添加到字符串中
for (const auto& code : eachCodes) {
char base = 'a';
str += static_cast<char>(code + base); // 将数字编码转换为字符
}
result.push_back(str); // 将转换后的字符串加入结果向量
}
return result; // 返回存储了字符串的向量
}
// 根据用户自定义的列数,将 vector<int> 中的数据存储进二维数组
std::vector<std::vector<int>> convertToMatrix(const std::vector<std::vector<int>>& Codes, int cols, int rows) {
//计数器
int count = 0;
vector<int> codes; //将Codes中的数字编码存入vector<int>型容器中
//初始矩阵
std::vector<std::vector<int>> Initial_matrix(rows, std::vector<int>(cols, 0));
//类型转换
for (const auto& eachcodes : Codes) {
for (const auto& code : eachcodes) {
codes.push_back(code); // 将 Codes 中的所有元素存入 codes
}
}
// 按行优先填充矩阵
for (int i = 0; i < rows; ++i) { // 遍历每一行
for (int j = 0; j < cols; ++j) { // 遍历每一列
if (count < codes.size()) { // 确保 count 不越界
Initial_matrix[i][j] = codes[count];
count++;
}
else {
// 如果 codes 数据不足以填满矩阵,可以选择填充默认值(如 0)
Initial_matrix[i][j] = 0;
}
}
}
return Initial_matrix; // 返回二维数组
}
//计算矩阵的行数
int Count_rows(int cols, int num) {
int rows;
if (num % cols == 0) {
rows = num / cols;
}
else {
rows = num / cols + 1;
}
return rows;
}
//计算密码的位数
int Count(const std::vector<string>& name) {
int num = 0;
for (const auto& str : name) {
// 遍历字符串中的每个字符
for (const auto& ch : str) {
num++;
}
}
return num;
}
// 进行矩阵乘法,输入的两个矩阵数据类型均为int型,返回相乘后的矩阵int型
std::vector<std::vector<int>> multiplyMatrices(const std::vector<std::vector<int>>& A, const std::vector<std::vector<int>>& B) {
int rowsA = A.size();
int colsA = A[0].size();
int colsB = B[0].size();
// 初始化结果矩阵 C,大小为 rowsA x colsB
std::vector<std::vector<int>> C(rowsA, std::vector<int>(colsB, 0));
// 矩阵乘法计算
for (int i = 0; i < rowsA; ++i) {
for (int j = 0; j < colsB; ++j) {
for (int k = 0; k < colsA; ++k) {
C[i][j] += (A[i][k] * B[k][j]);
}
C[i][j] = C[i][j] % 26;
}
}
return C;
}
// 打印分割线
void printSeparator(int length, char character) {
for (int i = 0; i < length; ++i) {
cout << character;
}
cout << endl;
}
//以下内容为求矩阵的逆矩阵
// 计算矩阵的行列式
int determinant(const vector<vector<int>>& mat, int n) {
if (n == 1) {
return mat[0][0];
}
int det = 0;
vector<vector<int>> cofactorMat(n, vector<int>(n));
for (int i = 0; i < n; i++) {
cofactorMat = getCofactor(mat, 0, i, n);
det += (i % 2 == 0 ? 1 : -1) * mat[0][i] * determinant(cofactorMat, n - 1);
}
return det;
}
// 获取指定位置的余子式矩阵
vector<vector<int>> getCofactor(const vector<vector<int>>& mat, int p, int q, int n) {
vector<vector<int>> temp(n - 1, vector<int>(n - 1));
int row = 0, col = 0;
for (int i = 0; i < n; i++) {
if (i == p) continue;
col = 0;
for (int j = 0; j < n; j++) {
if (j == q) continue;
temp[row][col] = mat[i][j];
col++;
}
row++;
}
return temp;
}
// 计算伴随矩阵
vector<vector<int>> adjoint(const vector<vector<int>>& mat, int n) {
vector<vector<int>> adj(n, vector<int>(n));
if (n == 1) {
adj[0][0] = 1;
return adj;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
vector<vector<int>> cofactorMat = getCofactor(mat, i, j, n);
int cofactor = determinant(cofactorMat, n - 1);
adj[j][i] = ((i + j) % 2 == 0 ? 1 : -1) * cofactor;
}
}
return adj;
}
// 计算矩阵的逆矩阵
vector<vector<int>> invertMatrix(const vector<vector<int>>& matrix, int n) {
// 1. 计算矩阵的行列式
int det = determinant(matrix, n);
if (det == 0) {
throw runtime_error("矩阵不可逆,行列式为 0.");
}
// 2. 计算伴随矩阵
vector<vector<int>> adj = adjoint(matrix, n);
// 3. 矩阵行列式的倒数与伴随矩阵相乘,得到逆矩阵
vector<vector<int>> inverse(n, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
inverse[i][j] = adj[i][j] / det; // 每个元素与行列式倒数相乘
}
}
return inverse;
}
int main() {
vector<int> transition;
vector<vector<int>> Codes;
vector<string> result;
vector<string>ciphertext;
vector<vector<int>> Initial_matrix;
vector<vector<int>> Key_matrix;
vector<vector<int>> MultiplyMatrice;
vector<vector<int>> Encryption_matrix;
vector<vector<int>> inverse_matrix;
int judge;
cout << "密码名称:希尔密码" << endl;
while (1) {
int num;
int cols;
int rows;
vector<string> name;
string input;
cout << "输入1选择加密功能,输入2选择解密功能,输入其它任意数字结束程序" << endl;
cin >> judge;
std::getline(std::cin, input); // 获取回车
if (judge == 1) {
cout << "已进入加密功能" << endl;
printSeparator(30, '-');
//输入明文
InputName(name, input);
int n = 0;
for (const string& ch : name) {
n += ch.size();
}
printSeparator(30, '-');
//计算明文的位数
Codes = convertToFigure(name);
num = Count(name);
cout << "明文位数为:" << num << endl;
printSeparator(30, '-');
//输入明文矩阵列数
cout << "请输入明文矩阵的列数" << endl;
cin >> cols;
cout << "明文矩阵列数为:" << cols << endl;
printSeparator(30, '-');
//计算明文矩阵的行数
rows = Count_rows(cols, num);
cout << "明文矩阵行数为:" << rows << endl;
printSeparator(30, '-');
//将明文数字编码存入二维矩阵中
Initial_matrix = convertToMatrix(Codes, cols, rows);
cout << "初始矩阵为:" << endl;
printMatrix(Initial_matrix);
printSeparator(30, '-');
//输入加密矩阵
int Key_rows = cols;
int Key_cols = cols;
cout << "加密矩阵的行数为:" << Key_rows << "加密矩阵的列数为:" << Key_cols << endl;
Key_matrix = Input_matrix(Key_cols, Key_rows);
cout << "加密矩阵为:" << endl;
printMatrix(Key_matrix);
printSeparator(30, '-');
//矩阵乘法计算并输出
MultiplyMatrice = multiplyMatrices(Initial_matrix, Key_matrix);
cout << "加密后的矩阵为:" << endl;
printMatrix(MultiplyMatrice);
printSeparator(30, '-');
//输出密文
cout << "密文为:" << endl;
ciphertext = convertToStrings(MultiplyMatrice);
output(ciphertext, n);
}
else if (judge == 2) {
cout << "已进入解密功能" << endl;
printSeparator(30, '-');
//输入密文
InputName(name, input);
int n = name.size();
printSeparator(30, '-');
//计算密文的位数
Codes = convertToFigure(name);
num = Count(name);
cout << "密文位数为:" << num << endl;
printSeparator(30, '-');
//输入加密矩阵
int Key_rows;
int Key_cols;
cout << "加密矩阵的行数和列数(必须相等):" << endl;
cin >> Key_rows;
cin >> Key_cols;
cout << "加密矩阵的行数为:" << Key_rows << "加密矩阵的列数为:" << Key_cols << endl;
Key_matrix = Input_matrix(Key_cols, Key_rows);
cout << "加密矩阵为:" << endl;
printMatrix(Key_matrix);
printSeparator(30, '-');
//密文转化为矩阵
//计算密文的列数
cols = Key_rows;
cout << "密文矩阵的列数为:" << cols << endl;
//计算密文矩阵的行数
rows = Count_rows(cols, num);
cout << "明文矩阵行数为:" << rows << endl;
//将密文数字编码存入二维矩阵中
Encryption_matrix = convertToMatrix(Codes, cols, rows);
cout << "初始矩阵为:" << endl;
printMatrix(Encryption_matrix);
printSeparator(30, '-');
//计算明文矩阵
//1.求加密矩阵的逆
inverse_matrix = invertMatrix(Key_matrix, cols);
cout << "加密矩阵的逆矩阵为:" << endl;
printMatrix(inverse_matrix);
printSeparator(30, '-');
vector<vector<int>> matrix;
//2.密文与加密矩阵的逆矩阵进行乘法
matrix = multiplyMatrices(Encryption_matrix, inverse_matrix);
cout << "明文矩阵为:" << endl;
printMatrix(matrix);
printSeparator(30, '-');
//将明文矩阵还原为明文并输出
cout << "明文为:" << endl;
result = convertToStrings(Initial_matrix);
output(result, n);
}
else {
break;
}
}
return 0;
}