密码学学习1——古典密码

密码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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值