四种密码算法代码

这里罗列一下凯撒密码、仿射密码、希尔密码和维吉尼亚密码的原理和算法的代码。
1、凯撒密码
根据公式:C=(x+k)mod26计算密文。输入一个k的值,从a-z分别对应0-25,明文字母对应的数字加k值后mod26得到对应的字母即为密文字母。对应的解密公式为:D=(x-k)mod26。

#include
#include
using namespace std;
#include
int main()
{
	cout << "请输入密钥k:" << endl;
	int k;
	cin >> k;
	char a[26];
	int j = 0;
	for (int i = 0; i < 26; i++)
	{
		a[i] = 'a'+j;
		j++;
	}
	int p = 0;
	string str = "hello";
	cout <<"明文为:"<<str << endl;
	char ch[30];
	for (int i = 0; i < str.length(); i++)
	{
		int j;
		for (j = 0; j < 26; j++)
			if (str[i] == a[j])
				break;
		int m = (j + k) % 26;
		ch[p++] = a[m];
	}
	cout << "密文为:";
	for (int q = 0; q < p; q++)
		cout << ch[q];
	cout << endl;
	p = 0;
	char c[30];
	for (int i = 0; i < str.length(); i++)
	{
		int j;
		for (j = 0; j < 26; j++)
			if (ch[i] == a[j])
				break;
		int m = (j - k) % 26;
		if (m < 0)
			m += 26;
		c[p++] = a[m];
	}
	cout << "解密结果为:" ;
	for (int q = 0; q < p; q++)
		cout << c[q];
	return 0;
}

2、仿射密码
仿射密码加密函数:C=(ax+b)mod26,当a=1的时候仿射密码为凯撒密码。解密函数为:D=a^(-1)(x-b)mod26,这里需要求一个a的乘法逆元。
因为我不太会求乘法逆元,所以这里提供一个最简单的就是直接遍历所有和26互质的数,即(ax)mod26=1。例:7模26的乘法逆元为15,7*15mod26=1。(解密的过程中会出现负数取模,直接加一个26再取就好了)

#include
using namespace std;
#include
int main()
{
	int a = 5, b = 8;
	string str = "fengziyu";
	cout << "明文为:" << str << endl;
	char c[30];
	int j = 0;
	cout << "密文为:";
	for (int i = 0; i < 26; i++)
	{
		c[i] = 'a' + j;
		j++;
	}
	char ch[30];
	int p = 0;
	for (int k = 0; k < str.length(); k++)
	{
		int l;
		for (l = 0; l < 26; l++)
			if (str[k] == c[l])
				break;
		int m = (a * l + b) % 26;
		ch[p++] = c[m];
	}
	for (int r = 0; r < p; r++)
		cout << ch[r];
	cout << endl << "解密结果:" ;
	int prime[26],d=0;
	for (int n = 1; n < 26; n++)//1-26之间所有和26互质的数
	{
		int temp,mid=n,m=26;
		while (1)
		{
			temp = m % mid;
			if (temp == 0)
				break;
			m = mid;
			mid = temp;
		}
		if (mid == 1)//两数互质
			prime[d++] = n;
	}
	for (int n = 0; n < d; n++)
	{
		if ((a * prime[n]) % 26 == 1)//得到逆元
		{
			for (int k = 0; k < str.length(); k++)
			{
				int l;
				for (l = 0; l < 26; l++)
					if (ch[k] == c[l])
						break;
				int f = l - b;
				if (f < 0)
					f += 26;
				int m = (prime[n] * f) % 26;
				cout << c[m];
			}
			break;
		}
	}
	return 0;
}

3、希尔密码
设置密钥矩阵,此次实验中设置密钥矩阵为2*2矩阵,密文中每两个字母为一组,和密钥矩阵做矩阵乘法,得到的矩阵即为加密后的结果。解密时,求得密钥矩阵的逆矩阵后和密文做矩阵乘,得到解密结果。
(我这个写的比较麻烦了,中间很多地方可以用写个函数,这样就没那么多了。求逆矩阵和矩阵相乘的部分我是直接算的,没有用代码编。主要感受一下密码的算法~)

#include
using namespace std;
#include
int main()
{
	char a[26];
	int j = 0;
	for (int i = 0; i < 26; i++)
	{
		a[i] = 'a' + j;
		j++;
	}
	string str = "hello";
	cout << "明文为:" << str << endl;
	cout << "设密钥如下:" << endl;
	int b[2][2];
	b[0][0] = 4; b[0][1] = 9; b[1][0] = 3; b[1][1] = 7;
	for (int i = 0; i < 2; i++)//输出密钥矩阵
	{
		for (int j = 0; j < 2; j++)
			cout << b[i][j] << " ";
		cout << endl;
	}
	int d = 0, h[20];
	for (int k = 0; k < str.length(); k++)
	{
		int j;
		for (j = 0; j < 26; j++)
		{
			if (str[k] == a[j])
				break;
		}
		h[d++] = j;
	}
	int h1[2],f=0;
	char c1[26];//密文
	for (int k = 0; k < str.length(); k+=2)
	{
		h1[0] = h[k]; h1[1] = h[k + 1];
		c1[f++] = a[(h1[0] * b[0][0] + h1[1] * b[0][1])%26];
		c1[f++] = a[(h1[0] * b[1][0] + h1[1] * b[1][1]) % 26];
	}
	cout << "密文为:";
	for (int i = 0; i < str.length(); i++)
		cout << c1[i];
	cout << endl;
	cout << "经计算可得密钥矩阵的逆矩阵为:" << endl;
	b[0][0] = 7; b[0][1] = -9; b[1][0] = -3; b[1][1] = 4;
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 2; j++)
			cout << b[i][j] << " ";
		cout << endl;
	}
	cout << "解密结果为:" << endl;
	d = 0; f = 0;
	for (int k = 0; k < str.length(); k++)
	{
		int j;
		for (j = 0; j < 26; j++)
		{
			if (c1[k] == a[j])
				break;
		}
		h[d++] = j;
	}
	int h2[30];
	char c2[20];//解密结果
	for (int k = 0; k < str.length(); k += 2)
	{
		h2[0] = h[k]; h2[1] = h[k + 1];
		int x = h2[0] * b[0][0] + h2[1] * b[0][1];
		if (x < 0)
			while (x < 0)
				x += 26;
		c2[f++] = a[x % 26];
		int y = h2[0] * b[1][0] + h2[1] * b[1][1];
		if (y < 0)
			while(y<0)
				y += 26;
		c2[f++] = a[y % 26];
	}
	for (int i = 0; i < str.length(); i++)
		cout << c2[i];
	cout << endl;
	return 0;
}

4、维吉尼亚密码
设置n位密钥,给需要加密的密文对应循环相加密钥后模26,得到密文。即加密函数为:C=(P-K)mod26,解密函数为:D=(C-K)mod26。

#include
using namespace std;
#include
#include
void match_number(int b[], char a[], string s)
{
	int k = 0;
	for (int i = 0; i < s.length(); i++)
	{
		int j;
		for (j = 0; j < 26; j++)
			if (s[i] == a[j])
				break;
		b[k++] = j;
	}
}
int main()
{
	string str = "csdn";
	cout << "设置密钥为:" << str << endl;
	string st = "helloworld";
	cout << "加密文本为:" << st << endl;
	char a[26];
	for (int i = 0; i < 26; i++)//26个字母
		a[i] = 'a' + i;
	int b[20];//原文对应数字
	int c[20];//密钥对应的数字
	int d[20];//密文对应的数字
	match_number(b, a, st);
	match_number(c, a, str);
	cout << "加密结果为:";
	for (int i = 0, j = 0; i < st.length(); i++, j++)
	{
		if (j >= str.length())
			j = 0;
		d[i] = (b[i] + c[j]) % 26;
	}
	char e[20];//密文结果
	int f[20];//解密对应的数字
	for (int i = 0; i < st.length(); i++)
		e[i] = a[d[i]];
	for (int i = 0; i < st.length(); i++)
		cout << e[i];
	cout << endl;
	cout << "解密结果为:";
	for (int i = 0, j = 0; i < st.length(); i++, j++)
	{
		if (j >= str.length())
			j = 0;
		int x = d[i] - c[j];
		if (x < 0)
			x += 26;
		f[i] = x % 26;
	}
	for (int i = 0; i < st.length(); i++)
		cout << a[f[i]];
	cout << endl;
	return 0;
}

如有错误,欢迎指正。

你可能感兴趣的:(学习问题,密码学)