编写实现古典密码的程序,能对给定的明文或密文进行正确的加密和解密。
(1) 仿射密码
参数选取:模数n=26+10=36,k2为学号后2位;k1为与学号后2位最近的素数。
加解密:加密自己名字的全拼和学号,再解密。
加密代码:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
/*
(1) 仿射密码
参数选取:模数n=26+10=36,k2为学号后2位;k1为与学号后2位最近的素数。
加解密:加密自己名字的全拼和学号,再解密。
*/
int n = 36;
string m, c;
int buff[32], len = 0, k1 = 0, k2 = 0;
cout << "输入明文:" << endl;
cin >> m;
cout << "输入k1:";
cin >> k1;
cout << "输入k2:";
cin >> k2;
//把明文转化成10进制整数,0-9,a-z分别代表十进制0-36
for (int i = 0; m[i] != ' '; i++)
{
//字母转10进制整数
if (m[i] > '9')
buff[i] = m[i] - 87;
else
buff[i] = m[i] - 48;//0ASCII为48
len++;
}
//加密运算,C=k1*m+k2 mod n;
for (int i = 0; i < len; i++)
{
buff[i] = (buff[i] * k1 + k2) % n;
}
//把数字对应为密文空间内的字符
for (int i = 0; i < len; i++)
{
if (buff[i] < 10)
m[i] = buff[i] + 48;
else
m[i] = buff[i] + 87;
}
cout << "密文为:" << endl;
for (int i = 0; i<len; i++)
{
cout << m[i];
}
cout << endl;
//解密,M=(C-k2)*k1^(-1)
system("pause");
return 0;
}
解密代码:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
//求解x^(-1)mod p
int GetIne(int x, int p)
{
for (int i = 0; i<p; i++)
{
if (x*i%p == 1)
{
x = i;
break;
}
}
return x;
}
int main()
{
/*
(1) 仿射密码
参数选取:模数n=26+10=36,k2为学号后2位;k1为与学号后2位最近的素数。
加解密:加密自己名字的全拼和学号,再解密。
*/
int n = 36;
string m, c;
int buff[32], len = 0, k1 = 0, k2 = 0, k = 0;
cout << "输入密文:" << endl;
cin >> m;
cout << "输入k1:";
cin >> k1;
cout << "输入k2:";
cin >> k2;
//把明文转化成10进制整数,0-9,a-z分别代表十进制0-36
//解密,M=(C-k2)*k1^(-1)
for (int i = 0; m[i] != ' '; i++)
{
//字母转10进制整数
if (m[i] > '9')
buff[i] = m[i] - 87;
else
buff[i] = m[i] - 48;//0ASCII为48
len++;
}
//解密运算,M=(C-k2)*k1^(-1)
k = GetIne(k1, n);
for (int i = 0; i < len; i++)
{
buff[i] = ((buff[i] - k2)*k) % n;
if (buff[i] < 0)
buff[i] += n;
//buff[i] = (buff[i] * k1 + k2) % n;
}
//把数字对应为明文空间内的字符
for (int i = 0; i < len; i++)
{
if (buff[i] < 10)
m[i] = buff[i] + 48;
else
m[i] = buff[i] + 87;
}
cout << "明文为:" << endl;
for (int i = 0; i<len; i++)
{
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}
(2) 置换密码
参数选取:分组长度为7;置换关系随机选取;
加解密:加密自己名字的全拼和学号(长度不足时后面全补填充长度),再解密。
加密代码:
/*置换密码
参数选取:分组长度为7;置换关系随机选取;
加解密:加密自己名字的全拼和学号(长度不足时后面全补
填充长度),再解密。
string中的函数:
swap()--交换字符
push_back() --插入字符
*/
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
system("title = 加密");
cout << "输入明文:" << endl;
cin >> m;
//cout << "string长度:" << m.size()<<endl;
////遍历明文
//for (int i=0;m[i]!=' ';i++)
//{
// cout << m[i];
//}
//cout << endl;
//如果明文不足7的倍数就填字符A
for (int i = m.size(); i % 7 != 0; i++)
{
m.push_back('A'); //在字符串后面插入字符A
}
//cout << "string长度:" << m.size() << endl;
////遍历
//for (int i = 0;i<m.size(); i++)
//{
// cout << m[i];
//}
//加密
for (int i = 0; i < m.size(); i += 7)
{
swap(m[i], m[i + 2]);//f(1)
swap(m[i], m[i + 6]);//f(2)
swap(m[i], m[i + 3]);//f(3)
swap(m[i], m[i + 0]);//f(4)
swap(m[i], m[i + 5]);//f(5)
swap(m[i], m[i + 1]);//f(6)
swap(m[i], m[i + 4]);//f(7)
}
//输出密文
cout << "密文为:" << endl;
for (int i = 0; i<m.size(); i++)
{
if (i != 0 && i % 7 == 0)
cout << endl;
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}
解密代码:
/*置换密码
参数选取:分组长度为7;置换关系随机选取;
加解密:加密自己名字的全拼和学号(长度不足时后面全补
填充长度),再解密。
string中的函数:
swap()交换字符
push_back()插入字符
*/
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
cout << "输入密文:" << endl;
cin >> m;
system("title = 解密");
//cout << "string长度:" << m.size()<<endl;
////遍历明文
//for (int i=0;m[i]!=' ';i++)
//{
// cout << m[i];
//}
//cout << endl;
//cout << "string长度:" << m.size() << endl;
////遍历
//for (int i = 0;i<m.size(); i++)
//{
// cout << m[i];
//}
//解密
for (int i = 0; i < m.size(); i += 7)
{
swap(m[i], m[i + 4]);//f(7)
swap(m[i], m[i + 1]);//f(6)
swap(m[i], m[i + 5]);//f(5)
swap(m[i], m[i + 0]);//f(4)
swap(m[i], m[i + 3]);//f(3)
swap(m[i], m[i + 6]);//f(2)
swap(m[i], m[i + 2]);//f(1)
}
//输出明文
cout << "明文为:" << endl;
for (int i = 0;m[i] != 'A'; i++)
{
/*if (i != 0 && i % 7 == 0)
cout << endl;*/
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}
(3) Hill密码 (例1.7)
加密代码:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
int buffer[4];
int a[4];//存放m*A mod 26的结果
int b[16];//存放m和A的转置矩阵的乘积
//矩阵A的转置矩阵
int A[] = { 8,6,5,10,
6,9,8,6,
9,5,4,11,
5,10,9,4 };
////A的逆矩阵的转置矩阵
//int B[] = { 23,2,2,25,
// 20,11,20,2,
// 5,18,6,22,
// 1,1,25,25 };
cout << "输入明文:" << endl;
cin >> m;
system("title = 加密");
//把字符转化成10进制整数
for (int i = 0; m[i] != ' '; i++)
{
buffer[i] = m[i] - 97;
}
cout << "buffer数组中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << buffer[i] << ",";
}
cout << endl;
//加密C = m * A mod 26,把结果放入数组a
for (int i = 0; i<16; i++)
{
b[i] = buffer[i % 4] * A[i];
}
cout << "b数组中的元素:" << endl;
for (int i = 0; i<16; i++)
{
cout << b[i] << ",";
}
cout << endl;
for (int i = 0; i < 16; i += 4)
{
a[i / 4] = (b[i] + b[i + 1] + b[i + 2] + b[i + 3]) % 26;
if (a[i / 4] < 0)
a[i / 4] += 26;
}
cout << "a数组中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << a[i] << ",";
}
cout << endl;
//转换为字符
cout << "密文为:" << endl;
for (int i = 0; i<4; i++)
{
m[i] = a[i] + 97;
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}
解密代码:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
int buffer[4];
int a[4];
int b[16];//存放m和A的转置矩阵的乘积
//矩阵A的转置矩阵
/*int A[] = { 8,6,5,10,
6,9,8,6,
9,5,4,11,
5,10,9,4 };*/
//A的逆矩阵的转置矩阵
int B[] = { 23,2,2,25,
20,11,20,2,
5,18,6,22,
1,1,25,25 };
cout << "输入密文:" << endl;
cin >> m;
system("title = 解密");
//把字符转化成10进制整数
for (int i = 0; m[i] != ' '; i++)
{
buffer[i] = m[i] - 97;
}
cout << "buffer数组中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << buffer[i] << ",";
}
cout << endl;
//解密M = C * B mod 26,把结果放入数组a,B是A的逆矩阵
for (int i = 0; i<16; i++)
{
b[i] = buffer[i % 4] * B[i];
}
cout << "b数组中的元素:" << endl;
for (int i = 0; i<16; i++)
{
cout << b[i] << ",";
}
cout << endl;
for (int i = 0; i < 16; i += 4)
{
a[i / 4] = (b[i] + b[i + 1] + b[i + 2] + b[i + 3]) % 26;
if (a[i / 4] < 0)
a[i / 4] += 26;
}
cout << "a数组中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << a[i] << ",";
}
cout << endl;
//转换为字符
cout << "明文为:" << endl;
for (int i = 0; i<4; i++)
{
m[i] = a[i] + 97;
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}