一、仿射密码的密码分析作业
密文
AOPCGUDEYKROIFKGBEFMCPIYCRARDEPBAQUFEPGHKJPKDDCJGKPJIEVCGEBEBAYCFAMCXCERIAREHAFFERJGHCRAOKBBKYARRCEDKFAIGHCPCDCKDFCBKKMEFEMCGKXCOKRQKYYEBKYCERBHCCRJKVEIBKPSAQKUFJRKBIDCEMEGHKFCICRBCRQCARQKYDERSERJGEIQKRIAJCPCJRKBBKKXPAOHB
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
bool cmp (pair<char, int> a, pair<char, int> b) {
return a.second > b.second;
}
int exGcb(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int g = exGcb(b, a % b, x, y);
int tmp = x;
x = y;
y = tmp - a / b * y;
return g;
}
int gcb(int a, int b) {
if (b == 0) return a;
return gcb(b, a % b);
}
int inverse(int tmp) {
int x, y;
exGcb(tmp, 26, x, y);
return (x % 26 + 26) % 26;
}
void hint(char e, char t, int a, int b, int inv) {
cout << "\n猜测 E 仿射成了 " << e << endl;
cout << "猜测 T 仿射成了 " << t << endl;
cout << "此时 a 为 " << a << ", b 为 " << b << ", a 的逆元为 " << inv << endl << "解码:";
}
int main() {
string str = "AOPCGUDEYKROIFKGBEFMCPIYCRARDEPBAQUFEPGHKJPKDDCJGKPJIEVCGEBEBAYCFAMCXCERIAREHAFFERJGHCRAOKBBKYARRCEDKFAIGHCPCDCKDFCBKKMEFEMCGKXCOKRQKYYEBKYCERBHCCRJKVEIBKPSAQKUFJRKBIDCEMEGHKFCICRBCRQCARQKYDERSERJGEIQKRIAJCPCJRKBBKKXPAOHB";
/*
* 打印每个字母出现次数,按字母出现次数排序。
*/
vector<pair<char, int>> ans;
ans.resize(26);
for (int i = 0; i < 26; i++) {
ans[i].first = (char) (65 + i);
}
for (char c : str) {
ans[c - 65].second++;
}
sort(ans.begin(), ans.end(), cmp);
// for (pair<char, int> p : ans) {
// cout << p.first << " ---- " << p.second << endl;
// }
/*
* 猜测 E 和 T 在前 z 个中
*/
int x, y, cur, z = 5, b, inv;
exGcb(15, 26, x, y);
for (int i = 0; i < z; i++) {
for (int j = 0; j < z; j++) {
if (i == j) continue;
cur = ans[j].first - ans[i].first;
int tmp = (x * cur % 26 + 26) % 26;
if (gcb(tmp, 26) != 1) continue;
b = (((4 * tmp) / 26 + 1) * 26 + (int) (ans[i].first) - 4 * tmp - 65) % 26;
inv = inverse(tmp);
hint(ans[i].first, ans[j].first, tmp, b, inv);
for (char c : str) {
cout << (char) (((inv * (c - 65 - b)) % 26 + 26) % 26 + 97);
}
cout << endl;
}
}
}
明文
猜测 E 仿射成了 C
猜测 T 仿射成了 R
此时 a 为 1, b 为 24, a 的逆元为 1
解码:cqreiwfgamtqkhmidghoerkaetctfgrdcswhgrijmlrmffelimrlkgxeigdgdcaehcoezegtkctgjchhgtlijetcqmddmacttegfmhckijerefemfhedmmoghgoeimzeqmtsmaagdmaegtdjeetlmxgkdmrucsmwhltmdkfegogijmheketdetsectsmafgtugtligksmtkclereltmddmmzrcqjd
猜测 E 仿射成了 C
猜测 T 仿射成了 B
此时 a 为 19, b 为 4, a 的逆元为 11
解码:igrewupamongslowtalkersmeninparticularwhodroppedwordsafewatatimelikebeansinahillandwhenigottominneapoliswherepeopletookalakewobegoncommatomeantheendofastoryicouldnotspeakawholesentenceincompanyandwasconsiderednottoobright
猜测 E 仿射成了 K
猜测 T 仿射成了 R
此时 a 为 23, b 为 22, a 的逆元为 17
解码:qulyospgietuwxeohgxmylwiytqtpglhqcsxglofenleppynoelnwgjyoghghqiyxqmyrygtwqtgfqxxgtnofytquehheiqttygpexqwofylypyepxyheemgxgmyoeryuetceiigheiygthfyytnejgwhelkqcesxntehwpygmgofexywythytcyqtceipgtkgtnogwcetwqnylyntehheerlqufh
猜测 E 仿射成了 K
猜测 T 仿射成了 B
此时 a 为 15, b 为 2, a 的逆元为 7
解码:mgnacwhoyebgqvectovsanqyabmbhontmuwvoncjexnehhaxcenxqodacototmyavmsaraobqmbojmvvobxcjabmgetteymbbaohevmqcjanahaehvateesovosaceragebueyyoteyaobtjaabxedoqtenimuewvxbetqhaosocjevaqabtabuambueyhobiobxcoquebqmxanaxbetteernmgjt
猜测 E 仿射成了 E
猜测 T 仿射成了 B
此时 a 为 5, b 为 10, a 的逆元为 21
解码:ygboucjeiargkzautezqobkioryrjebtywczebupafbajjofuabfkexouetetyiozyqonoerkyrepyzzerfuporygattaiyrroejazykupobojoajzotaaqezeqouanogarwaiietaioertpoorfaxektabmywaczfratkjoeqeupazokortorwoyrwaijermerfuekwarkyfobofrattaanbygpt
猜测 E 仿射成了 R
猜测 T 仿射成了 C
此时 a 为 25, b 为 21, a 的逆元为 25
解码:vhgtpbsrxlehnqlpurqjtgnxtevesrguvfbqrgpolmglsstmplgmnratpruruvxtqvjtytrenverovqqrempotevhluulxveetrslqvnpotgtstlsqtulljrqrjtplythleflxxrulxtreuottemlarnulgdvflbqmelunstrjrpolqtnteuteftveflxsredremprnflenvmtgtmeluullygvhou
猜测 E 仿射成了 R
猜测 T 仿射成了 K
此时 a 为 3, b 为 5, a 的逆元为 9
解码:hdmzjfirptedbatjqralzmbpzeheirmqhvfarmjstkmtiizkjtmkbrozjrqrqhpzahlzgzrebhershaarekjszehdtqqtpheezritahbjszmziztiazqttlrarlzjtgzdtevtpprqtpzreqszzektorbqtmnhvtfaketqbizrlrjstazbzeqzevzhevtpirenrekjrbvtebhkzmzketqqttgmhdsq
猜测 E 仿射成了 B
猜测 T 仿射成了 C
此时 a 为 7, b 为 25, a 的逆元为 15
解码:prgtbdixljkrfmjbexmntgfltkpkixgepvdmxgbqjugjiitubjgufxstbxexepltmpntwtxkfpkxqpmmxkubqtkprjeejlpkktxijmpfbqtgtitjimtejjnxmxntbjwtrjkvjllxejltxkeqttkujsxfejgzpvjdmukjefitxnxbqjmtftketkvtpkvjlixkzxkubxfvjkfputgtukjeejjwgprqe
猜测 E 仿射成了 B
猜测 T 仿射成了 K
此时 a 为 11, b 为 9, a 的逆元为 19
解码:lrkxvbqjztwrhctvejcfxkhzxwlwqjkeldbcjkvotaktqqxavtkahjuxvjejelzxclfxgxjwhlwjolccjwavoxwlrteetzlwwxjqtclhvoxkxqxtqcxettfjcjfxvtgxrtwdtzzjetzxjweoxxwatujhetkpldtbcawtehqxjfjvotcxhxwexwdxlwdtzqjwpjwavjhdtwhlaxkxawteettgklroe
猜测 E 仿射成了 B
猜测 T 仿射成了 E
此时 a 为 21, b 为 21, a 的逆元为 5
解码:zrwjdvotpxgrnyxdetyhjwnpjgzgotwezbvytwdixswxoojsdxwsntajdtetezpjyzhjkjtgnzgtizyytgsdijgzrxeexpzggjtoxyzndijwjojxoyjexxhtythjdxkjrxgbxpptexpjtgeijjgsxatnexwlzbxvysgxenojthtdixyjnjgejgbjzgbxpotgltgsdtnbxgnzsjwjsgxeexxkwzrie
Process finished with exit code 0
二、代换密码的密码分析作业(没做出来)
密文
FSHFPMGHKCZMZSOMGTIMGHTIYCDLMFOCCHRUZCHVPTIMGHTIDOCFULVCCILCFNINDZGIEHMCGHTIMZYIFLTIMGHTHAPFCMGHZVGMGHINHAZIMHBDMZFSVZPDYFSPZCTIMGIMDFUIKZBBNHIKTFVMAZPPGZVNFFWKMZYIBNIYILGDZVINWSFKBHAOMZYVZSYBZSOVISAPZBZMDISAZHASFMMFBNIYWOCFIMZYIBMFTFVMLICMFEHMKFHJVHSATHISFUYISPFCMZFSHTIZCHMGHPZCICAHAIUAZYUBMMGZIVAHYZAZWOCFUSAMCFIAVUNQHFPVHEHCUAZSOSUTZHBAVBZSZSPFCTIMIVVUTHMFUSAISAMGFBVIVMGHSFMHMGIMHCYZVHVLHTIZBKZMMUSIMHBDBKGZYGZSVMFSHMFAZVWFPPFUSOVINFUMSOGFKTUYFZSYBUAHHYMISAZMIBICHIVFNHCMGHFCHICIBOHNZFSMGHFCFTUYGTIMUVZAHEHBDICHSHHAZPDFUPZSBHIVHZTTGMGHVFBUCHYHZEHIPFCTVDFUFMGIMDFUCON
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
bool cmp(pair<string, int> a, pair<string, int> b) {
return a.second > b.second;
}
void more(string str, int x) {
map<string, int> m;
vector<pair<string, int>> ans;
string tmp;
for (int i = 0; i < str.size() - x + 1; i++) {
tmp = str.substr(i, x);
if (m.find(tmp) == m.end()) {
m[tmp] = 1;
} else m[tmp]++;
}
for (auto & it : m) {
ans.emplace_back(it.first, it.second);
}
sort(ans.begin(), ans.end(), cmp);
for (auto i = 0; i <= 30; i++) {
cout << ans[i].first << " --- " << ans[i].second << "\t";
}
cout << endl;
}
void show(string str) {
cout << str << endl;
string tmp;
int c[27];
memset(c, 0, sizeof(c));
c[8] = 5; // H 是 E
c[13] = 20; // M 是 T
c[9] = 1; // I 是 A
c[6] = 15; // F 是 O
c[26] = 9; // Z 是 I
c[19] = 14; // S 是 N
c[3] = 19; // C 是 S
c[7] = 8; // G 是 H
// c[20] = 18; // T 是 R
c[22] = 12; // V 是 L
c[1] = 4; // A 是 D
// 语境中
c[16] = 6; // P 是 F
c[15] = 7; // O 是 G
// c[9] = 15;
// c[6] = 1;
for (int i = 0; i < str.size(); i++) {
if (c[str[i] - 64] != 0) {
tmp.push_back((char) (c[str[i] - 64] + 96));
} else tmp.push_back('_');
}
cout << tmp << endl;
}
int main() {
string str = "FSHFPMGHKCZMZSOMGTIMGHTIYCDLMFOCCHRUZCHVPTIMGHTIDOCFULVCCILCFNINDZGIEHMCGHTIMZYIFLTIMGHTHAPFCMGHZVGMGHINHAZIMHBDMZFSVZPDYFSPZCTIMGIMDFUIKZBBNHIKTFVMAZPPGZVNFFWKMZYIBNIYILGDZVINWSFKBHAOMZYVZSYBZSOVISAPZBZMDISAZHASFMMFBNIYWOCFIMZYIBMFTFVMLICMFEHMKFHJVHSATHISFUYISPFCMZFSHTIZCHMGHPZCICAHAIUAZYUBMMGZIVAHYZAZWOCFUSAMCFIAVUNQHFPVHEHCUAZSOSUTZHBAVBZSZSPFCTIMIVVUTHMFUSAISAMGFBVIVMGHSFMHMGIMHCYZVHVLHTIZBKZMMUSIMHBDBKGZYGZSVMFSHMFAZVWFPPFUSOVINFUMSOGFKTUYFZSYBUAHHYMISAZMIBICHIVFNHCMGHFCHICIBOHNZFSMGHFCFTUYGTIMUVZAHEHBDICHSHHAZPDFUPZSBHIVHZTTGMGHVFBUCHYHZEHIPFCTVDFUFMGIMDFUCON";
for (int i = 1; i < 8; i++)
more(str, i);
show(str);
/*
* 已确定的:T(M) H(G) E(H) R(T)
* 猜测:A(I)
* 假设 H、M、I 其中一个为 E。
* H、M、I、F、Z 猜测从 T、A、O、I、N、S、H、R 中取。
* 找形如 _H、H_、_M、M_、_I、I_。
* GH --- 12 HI --- 7 CH --- 7 HT --- 6 HM --- 6 HA --- 6 EH --- 5 AH --- 4
* HE ER RE ED ES EN EA ET TE SE
* 初步猜测 A = R
* AZ SA HA
*/
return 0;
}
三、维吉尼亚密码的密码分析
密文
KCCPKBGUFDPHQTYAVINRRTMVGRKDNBVFDETDGILTXRGUDDKOTFMBPVGEGLTGCKQRACQCWDNAWCRXIZAKFTLEWRPTYCQKYVXCHKFTPONCQQRHJVAJUWETMCMSPKQDYHJVDAHCTRLSVSKCGCZQQDZXGSFRLSWCWSJTBHAFSIASPRJAHKJRJUMVGKMITZHFPDISPZLVLGWTFPLKKEBDPGCEBSHCTJRWXBAFSPEZQNRWXCVYCGAONWDDKACKAWBBIKFTIOVKCGGHJVLNHIFFSQESVYCLACNVRWBBIREPBBVFEXOSCDYGZWPFDTKFQIYCWHJVLNHIQIBTKHJVNPIST
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iomanip>
using namespace std;
double book[26] = {0.082, 0.015, 0.028, 0.043, 0.127, 0.022, 0.02,
0.061, 0.07, 0.002, 0.008, 0.04, 0.024, 0.067,
0.075, 0.019, 0.001, 0.06, 0.063, 0.091, 0.028,
0.01, 0.023, 0.001, 0.02, 0.001};
vector<pair<char, double>> store;
bool cmp(pair<char, double> a, pair<char, double> b) {
return a.second > b.second;
}
/*
* 计算当前字符串的重合指数
*/
void one(string str, int x) {
int ans[26], len = str.length();
double sum = 0;
memset(ans, 0, sizeof(ans));
for (char c : str) {
ans[c - 65]++;
}
for (int i = 0; i < 26; i++) {
sum += (book[i] * ans[i] / len);
}
store[x] = pair<char, double>(char (x + 65), sum);
}
/*
* 将密文进行移位
*/
void move(string str) {
for (int i = 0; i < 26; i++) {
string tmp;
for (char c : str) {
tmp.push_back(char (((c - 65 - i) % 26 + 26) % 26 + 65));
}
one(tmp, i);
}
}
/*
* 将密文分解成 m 部分
*/
void split(string str, int m) {
string strs[m];
int mod;
for (int i = 0; i < str.length(); i++) {
mod = i % 6;
strs[mod].push_back(str[i]);
}
for (string s : strs) {
store.clear();
store.resize(26);
move(s);
sort(store.begin(), store.end(), cmp);
for (int i = 0; i < store.size(); i++) {
cout << store[i].first << " --- " << setiosflags(ios::fixed) << setprecision(4) << store[i].second << "\t";
if ((i + 1) % 7 == 0) cout << endl;
}
cout << "\n\n";
}
}
int main() {
string str = "KCCPKBGUFDPHQTYAVINRRTMVGRKDNBVFDETDGILTXRGUDDKOTFMBPVGEGLTGCKQRACQCWDNAWCRXIZAKFTLEWRPTYCQKYVXCHKFTPONCQQRHJVAJUWETMCMSPKQDYHJVDAHCTRLSVSKCGCZQQDZXGSFRLSWCWSJTBHAFSIASPRJAHKJRJUMVGKMITZHFPDISPZLVLGWTFPLKKEBDPGCEBSHCTJRWXBAFSPEZQNRWXCVYCGAONWDDKACKAWBBIKFTIOVKCGGHJVLNHIFFSQESVYCLACNVRWBBIREPBBVFEXOSCDYGZWPFDTKFQIYCWHJVLNHIQIBTKHJVNPIST";
split(str, 6);
return 0;
}
@Test
public void test7() {
int book[] = {2, 17, 24, 15, 19, 14};
StringBuffer sb = new StringBuffer();
for (int i = 0; i < str2.length(); i++) {
sb.append((char) (((str2.charAt(i) - book[i % 6] - 65) % 26 + 26) % 26 + 65));
}
System.out.println(sb);
}
明文
ILEARNEDHOWTOCALCULATETHEAMOUNTOFPAPERNEEDEDFORAROOMWHENIWASATSCHOOLYOUMULTIPLYTHESQUAREFOOTAGEOFTHEWALLSBYTHECUBICCONTENTSOFTHEFLOORANDCEILINGCOMBINEDANDDOUBLEITYOUTHENALLOWHALFTHETOTALFOROPENINGSSUCHASWINDOWSANDDOORSTHENYOUALLOWTHEOTHERHALFFORMATCHINGTHEPATTERNTHENYOUDOUBLETHEWHOLETHINGAGAINTOGIVEAMARGINOFERRORANDTHENYOUORDERTHEPAPER
四、希尔密码的密码分析
明文 + 密文
breathtaking + rupotentoifv
#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
using namespace std;
int main() {
string str = "breathtaking";
int mod = str.length() % 3;
for (int i = 0; i < mod; i++) {
str.push_back('a');
}
int k[3][3] = {{3, 21, 20}, {4, 15, 23}, {6, 14, 5}};
vector<int> ans;
for (int i = 2; i < str.length(); i += 3)
for (int j = 0; j < 3; j++) {
ans.push_back(((str[i - 2] - 97) * k[0][j] +
(str[i - 1] - 97) * k[1][j] +
(str[i] - 97) * k[2][j])% 26);
}
for (int i : ans)
cout << (char) (i + 97);
return 0;
}