仿射密码解密 频率法

密码作业
仿射密码解密 频率法

文本控制输入输出
中间代码有参考

从密文中获得字母频次统计表。
C→E,K→T 4a+b=2,19a+b=10 得到的解与可mod26所有的合法值比较
s[14] = { 1,1,3,9,5,21,7,15,11,19,17,23,25,25 },在s中为则合法解,不在则为不合法解。
求出a逆,得到解密方程。
解密出明文看是否有意义。
有意义则解密结束,否则仍需继续遍历字母频次统计表以找到合法的解密方程。

密文

AOPCGUDEYKROIFKGBEFMCPIYCRARDEPBAQUFEPGHKJPKDDCJGKPJIEVCGEBEBAYCFAMCXCERIAREHAFFERJGHCRAOKBBKYARRCEDKFAIGHCPCDCKDFCBKKMEFEMCGKXCOKRQKYYEBKYCERBHCCRJKVEIBKPSAQKUFJRKBIDCEMEGHKFCICRBCRQCARQKYDERSERJGEIQKRIAJCPCJRKBBKKXPAOHB
明文
Igrewupaicularwhlikebeanneapolisgoncommaldnotspeyandwascmongslowodroppedsinahillwherepeotomeanthakawholeonsideretalkersmwordsafeandwhenipletookaeendofassentencednottoobeninpartwatatimegottominlakewobetoryicouincompanright
代码

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>      
#include <vector>       
#include <algorithm> 
using namespace std;

typedef pair<char, int> PAIR;
bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) {
	return lhs.second > rhs.second;
}
struct CmpByValue {
	bool operator()(const PAIR& lhs, const PAIR& rhs) {
		return lhs.second > rhs.second;
	}
};

int s[14] = { 1,1,3,9,5,21,7,15,11,19,17,23,25,25 };

int search(int s[], int y, int x) /*被调用的函数search()*/
{
	int i, f = -1;
	for (i = 0; i < 14; i++)
	{
		if (x == s[i])//查找到所需的元素,跳出循环
		{
			f = i + 1;
			break;
		}
	}
	return(f);
}


int main() {

	ifstream in("D:/test/1/in.txt");
	ofstream out("D:/test/1/output.txt");
	string filename;
	string line;

	if (in) // 有该文件
	{
		while (getline(in, line)) // line中不包括每行的换行符
		{
			map<char, int> m;
			for (auto i : line)
			{
				m[i]++;
			}
			for (auto& i : m)
			{
				cout << i.first << ' ' << i.second << endl;
			}

			vector<PAIR> m_vec(m.begin(), m.end());
			sort(m_vec.begin(), m_vec.end(), CmpByValue());

			int j;
			j = m_vec.size();

			char* p_str = new char[j];
			for (int i = 0; i != m_vec.size(); ++i)
			{
				cout << m_vec[i].first << " " << m_vec[i].second << endl;
			}

			for (int i = 0; i != m_vec.size(); ++i)
			{
				p_str[i] = m_vec[i].first;
				//cout << " p_str  " << p_str[i] << endl;

			}

			int a, b, c, d, e, f;
			a = 4;
			b = 1;
			c = m_vec[0].first - 65;
			cout << p_str[0] << endl;
			d = 19;
			e = 1;
			//f = m_vec[1].first - 65;
			//方程不变量赋值
			int x = 0; 
			int y = 0;
			int pos=-1;
			for (int n = 1; n < j; n++) {

				cout << p_str[n] << endl;
				f = m_vec[n].first - 65;
				cout << "m_vec[n].firs  " << m_vec[n].first<< f << endl;
				//方程找t的匹配字符从第二频次开始 n=1开始 ,m_vec[1].first
				cout << "第 n: " << n << " 频次 " << endl;
				//解x和y
				
				int p = 1;
				do {
					x = (f - c + 26 * p);
					
					p++;

				} while (x % 15 != 0);
				x = x / 15;
				cout << " x: " << x << endl;

				p = 0;
				do {
					//cout << "求y的 p: " << p << endl;
					y = c - 4 * x + 26 * p;
					p++;
					
				} while (y < 1);
				cout << a << " |  " << b << " |  " << c << " |  " << d << " |  " << e << " |  " << f << endl;
				cout << " x: " << x << endl;
				cout << " y: " << y << endl;

				pos = search(s, 10, x); /*调用函数search()完成顺序查找*/
				cout << "pos数" << pos << endl;
				if (pos < 0) /*输出要找的数的位置*/
				{
					cout << "没找到要找的数" << endl;
			
				}
				else
				{
					cout << "您要找的数:   " << x << "  在数组中第 个元素处 " << pos << endl;
					cout << "找到要的字母" << m_vec[n].first << endl;
					break;
				}

			}
			int ani = 0;
			if (pos % 2 == 0)
				{
				ani = s[pos - 2];
				}
			else { ani = s[pos - 1]; }

			cout << "您要找的a逆:   " << ani << endl;

			cout << "解密函数x=" << ani << "(y- " << y << ")mod26 " << endl;

				int sl;
				sl = line.length();

				char ch[500];
				char re[500];
				strcpy_s(ch, line.c_str());

				for(int p=0;p<sl;p++)
				{
				
					
					re[p] =( ani * ((ch[p] - 65) - y)) % 26 + 97;
					if ((ani * ((ch[p] - 65) - y)) < 0) {
						re[p] = re[p] + 26;
					}
					cout << re[p];
					out << re[p]; // 输入到2.txt中
				}
		}
	}
	else // 没有该文件
	{
		cout << "no such file" << endl;
	}
	in.close();
	out.close();
	system("pause");
	return 0;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值