C++希尔密码三阶矩阵秘钥的加密/解密/求模26的逆/求解秘钥

本文详细介绍了一种经典的密码学算法——希尔密码的实现过程,包括加密、解密及求解秘钥等核心功能。文章通过C++代码展示了如何进行矩阵的模26乘运算、求逆以及希尔密码的具体应用,适用于信息安全、密码学研究和学习。
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;

string hill_cipher_encrypt(string& , vector<vector<int>>& );//希尔密码加密
string hill_cipher_decrypt(string& , vector<vector<int>>& );//希尔密码解密
void hill_cipher_calculate_key(string& , string& );//希尔密码求秘钥(仅3阶矩阵)
void print_matrix(vector<vector<int>>& );//打印矩阵
vector<vector<int>> matrix_mod26_mutiply(vector<vector<int>>&, vector<vector<int>>&);//矩阵模26乘运算
int matrix_mod26_mutiply_sub(vector<vector<int>>&, vector<vector<int>>&, int, int);//矩阵模26乘运算子函数(v1的第i行乘v2的第j列)
int inverse_matrix_mod26_sub(int i, int j, vector<vector<int>>& v);//求3阶矩阵在模26下的逆	子函数	求代数余子式
vector<vector<int>> inverse_matrix_mod26(vector<vector<int>>& v);//求3阶矩阵在模26下的逆

int main()
{
	//秘钥K
	vector<vector<int>> K = { {1,11,12},{4,23,2},{17,15,9} };
	//明文1
	string plaintext = "lookingforwardtoournationalday";
	//加密得密文1
	string ciphertext = hill_cipher_encrypt(plaintext, K);
	//解密秘钥K模26逆
	vector<vector<int>> K_inverse = inverse_matrix_mod26(K);
	//验证加密是否正确
	string decrypto_plaintext = hill_cipher_decrypt(ciphertext, K_inverse);

	//明文2
	plaintext = "breathtaking";
	//密文2
	ciphertext = "RUPOTENTOIFV";
	//求解秘钥
	hill_cipher_calculate_key(plaintext, ciphertext);
}


//打印矩阵
void print_matrix(vector<vector<int>>& v)
{
	for (auto a : v)
	{
		for (auto b : a)
			cout << b << " ";
		cout << endl;
	}
}

//矩阵模26乘运算
vector<vector<int>> matrix_mod26_mutiply(vector<vector<int>>& v1, vector<vector<int>>& v2)
{
	vector<vector<int>> v;
	for (int i = 0; i < 3; i++)
	{
		vector<int> v_tp;
		for (int j = 0; j < 3; j++)
		{
			int tp = matrix_mod26_mutiply_sub(v1, v2, i, j);
			v_tp.push_back(tp);
		}
		v.push_back(v_tp);
	}
	return v;
}

//矩阵模26乘运算子函数(v1的第i行乘v2的第j列)
int matrix_mod26_mutiply_sub(vector<vector<int>>& v1, vector<vector<int>>& v2, int i, int j)
{
	int res = 0;
	for (int k = 0; k < 3; k++)
		res += v1[i][k] * v2[k][j];
	res = (res % 26 + 26) % 26;
	return res;
}

//求3阶矩阵在模26下的逆
vector<vector<int>> inverse_matrix_mod26(vector<vector<int>>& v)
{
	//求模26行列式值
	int A = v[0][0] * inverse_matrix_mod26_sub(0, 0, v) + v[0][1] * inverse_matrix_mod26_sub(0, 1, v)
		+ v[0][2] * inverse_matrix_mod26_sub(0, 2, v);
	A = (A % 26 + 26) % 26;	
	map<int, int> inverse;
	//模A可逆情况,其他情况不可逆
	inverse.insert(pair<int, int>(1, 1));
	inverse.insert(pair<int, int>(3, 9));
	inverse.insert(pair<int, int>(5, 21));
	inverse.insert(pair<int, int>(7, 15));
	inverse.insert(pair<int, int>(9, 3));
	inverse.insert(pair<int, int>(11, 19));
	inverse.insert(pair<int, int>(15, 7));
	inverse.insert(pair<int, int>(17, 23));
	inverse.insert(pair<int, int>(19, 11));
	inverse.insert(pair<int, int>(21, 5));
	inverse.insert(pair<int, int>(23, 17));
	inverse.insert(pair<int, int>(25, 25));
	if (inverse.find(A) == inverse.end())
	{
		cout << "矩阵模26不可逆" << endl;
		return v;
	}
	
	int rate = inverse[A];
	cout << "矩阵行列式模26值为" << A << endl;
	vector<vector<int>> v_mod26_inverse;
	for (int i = 0; i < 3; i++)
	{
		vector<int> v_tp;
		for (int j = 0; j < 3; j++)
		{
			int tp = (rate * inverse_matrix_mod26_sub(j, i, v) % 26 + 26) % 26;
			v_tp.push_back(tp);
		}
		v_mod26_inverse.push_back(v_tp);
	}
	cout << endl << "逆矩阵为:" << endl;
	print_matrix(v_mod26_inverse);
	cout << endl << "检验结果:" << endl;
	vector<vector<int>> muti = matrix_mod26_mutiply(v, v_mod26_inverse);
	print_matrix(muti);
	cout << "-----------------------" << endl;
	return v_mod26_inverse;
}

//求3阶矩阵在模26下的逆	子函数	求代数余子式
int inverse_matrix_mod26_sub(int i, int j, vector<vector<int>>& v)
{
	int i1 = 0;
	int i2 = 0;
	int j1 = 0;
	int j2 = 0;
	switch (i)
	{
	case 0:
		i1 = 1;
		i2 = 2;
		break;
	case 1:
		i1 = 0;
		i2 = 2;
		break;
	case 2:
		i1 = 0;
		i2 = 1;
		break;
	}
	switch (j)
	{
	case 0:
		j1 = 1;
		j2 = 2;
		break;
	case 1:
		j1 = 0;
		j2 = 2;
		break;
	case 2:
		j1 = 0;
		j2 = 1;
		break;
	}
	//求代数余子式
	int res = (i + j) % 2 == 0 ? 1 : -1;
	res *= (v[i1][j1] * v[i2][j2] - v[i1][j2] * v[i2][j1]);
	return res;
}

//希尔密码求秘钥(仅3阶矩阵)
void hill_cipher_calculate_key(string& plaintext, string& chipertext)
{
	vector<vector<int>> v1, v2;
	vector<int> tp1, tp2;
	for (int i = 0; i < 10; i++)
	{

		if (i % 3 == 0 && i != 0)
		{
			v1.push_back(tp1);
			v2.push_back(tp2);
			tp1.clear();
			tp2.clear();
		}
		tp1.push_back(plaintext[i] - 'a');
		tp2.push_back(chipertext[i] - 'A');
	}
	vector<vector<int>> v0 = inverse_matrix_mod26(v1);
	vector<vector<int>> v = matrix_mod26_mutiply(v0, v2);
	cout << "求得秘钥为:" << endl;
	print_matrix(v);
	cout << "-----------------------" << endl;
	string chiper = hill_cipher_encrypt(plaintext, v);
}

//希尔密码加密
string hill_cipher_encrypt(string& text, vector<vector<int>>& v)
{
	//65-90	A-Z	97-122	a-z
	if (text == "")
		return "error";

	string target = "";
	cout << "希尔密码明文:" << endl;
	cout << text << endl << endl;
	cout << "希尔密码秘钥:" << endl;
	print_matrix(v);
	int counter = 0;
	cout << endl;
	for (unsigned int i = 0; i < text.size(); i += 3)
	{
		char c1 = text.at(i) - 97;
		char c2 = text.at(i + 1) - 97;
		char c3 = text.at(i + 2) - 97;
		int a1 = c1;
		int a2 = c2;
		int a3 = c3;
		for (int j = 0; j < 3; j++)
		{
			int tp = c1 * v[0][j] + c2 * v[1][j] + c3 * v[2][j];
			tp = (tp % 26 + 26) % 26 + 65;
			char c = tp;
			target += c;
		}
	}
	cout << "希尔密码加密求得密文:" << endl;
	cout << target << endl;
	cout << "-----------------------" << endl;
	return target;
}

//希尔密码解密
string hill_cipher_decrypt(string& text, vector<vector<int>>& v)
{
	//65-90	A-Z	97-122	a-z
	if (text == "")
		return "error";

	string target = "";
	cout << "希尔密码密文:" << endl
		<< text << endl << endl
		<< "希尔密码秘钥逆矩阵:" << endl;
	print_matrix(v);
	int counter = 0;
	for (unsigned int i = 0; i < text.size(); i += 3)
	{
		char c1 = text.at(i) - 65;
		char c2 = text.at(i + 1) - 65;
		char c3 = text.at(i + 2) - 65;
		for (int j = 0; j < 3; j++)
		{
			int tp = c1 * v[0][j] + c2 * v[1][j] + c3 * v[2][j];
			tp = (tp % 26 + 26) % 26 + 97;
			char c = tp;
			target += c;
		}
	}
	cout << "希尔密码解密求得明文:" << endl
		<< target << endl
		<< "-----------------------" << endl;
	return target;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值