设计思路
1、 建立用于替换的表单;
2、 设计程序基本模块和实现基本输入输出的功能;
3、 逐个模块实现加密功能并测试;
4、 实现统计功能并测试;
程序演示
此代码可以实现直接的单词加密和文本加密,并在(4.实验分析与总结)中对文本加密后的密文进行了统计特征分析攻击。
代码展示(可用
#include<iostream>
#include<fstream>
#include<string>
#include<cstdlib>
using namespace std;
char a[26] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z' };//代换的表单
//默认密钥key = 3
int main() {
string cleartext, ciphertext;//文本输入输出时的文件名
hh:;
cout << "加密单词请按1,加密文本请按2,退出程序请按3" << endl;
int flag;//用来实现菜单功能
cin >> flag;
if (flag == 1) {
string word;
cin >> word;
int len = word.length();
for (int i = 0; i < len; i++) {
int j = i;
if (word[i] >= 'A'&&word[i] <= 'Z') {//处理大小写问题,统一化为小写
word[i] = word[i] - 'A' + 'a';
}
while (a[j] != word[i])//找到对应代换表中的位置
j++;
if (a[j] = word[i]) {//进行代换
j = (j + 3) % 26;//防止表溢出
word[i] = a[j];
}
}
cout << word << endl;
goto hh;
}
else if (flag == 2) {//文件输入输出不再进行字符频率统计,可以设置一个count检测读入次数并将字符分类来统计频率,此处不再演示。
ofstream fout;
ifstream fin;
char ch;
int c1[26] = { 0 }, c2[26] = { 0 }, c = 0;
cout << "请输入文本名:";
cin >> cleartext;
cout << endl << "请输入加密后输出的文件名:";
cin >> ciphertext;
fin.open(cleartext);//文本输入流建立关系
if (!fin.is_open()) {
cerr << "fail to open file" << cleartext << endl;
system("pause");
exit(0);
}
fout.open(ciphertext);//文本输出流建立关系
if (!fin.is_open()) {
cerr << "fail to open file" << ciphertext << endl;
system("pause");
exit(0);
}
while (fin.get(ch)) {//代换过程
int i = 0;
c++;
if (ch >= 'A'&&ch <= 'Z')
ch = ch - 'A' + 'a';
while (a[i] != ch)
i++;
if (a[i] == ch) {
c1[i]++;
i = (i + 3) % 26;
c2[i]++;
fout << a[i];
}
}
fin.close();//关闭流类库
fout.close();
cout << "密文概率:" << endl;
float rate;
for (int i = 0; i < 26; i++) {
rate = (float)c2[i] / c;
cout << a[i] << " : " << rate * 100 << "%" << endl;
}
goto hh;
}
else {
goto out;
}
out:;
return 0;
}
//解密算法可以将key置为 -3 ,此程序不再演示解密过程
统计分析
在对一个文本内容进行加密后统计,和英文字符频率进行对比,可用有效地推算出代替序列和明文。
有理由怀疑h对应的是明文e;w对应的是t;d对应的是a;考虑the这个单词使用频率较高,并且在两个频率表上进行对比,发现有充分的理由认为k对应的是h,则有理由推断替换的跨度为key = 3。