关键词密码是单表替代密码,选用某一个词组或短语经过处理作为密钥。
原理:
随机选择一个词组或短语作为密钥,如果该关键词中有重复字母,则去掉除第一次出现外的所有重复字母。例如选取关键词”nextlegend”,则处理后为”nextlgd”。
将处理后的关键词依次排列在字母表的下方,并将除去这些关键词后字母表中剩余的字母依次填入剩余空间。如下图:
像这样,上方的明文字母由下方的密文字母替换,即可实现加密。
解密即反向替换,通过密文得到明文。
例如,根据以上的对应关系,有:
明文:NEVER GIVE UP
密文:JLULP DBUL SM
特点:简单,脆弱。比凯撒密码略强。
破解:频率分析
加密代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#include<iostream> #include<string> #include<stdlib.h> #include<windows.h> using namespace std; int Check(string s) { //检查输入的字符串是否为纯英文 int i = 0; while (s[i] != '\0') { if (!((s[i] >= 'a'&&s[i] <= 'z') || (s[i] >= 'A'&&s[i] <= 'Z'))) { cout << "Error!Please enter again!" << endl; Sleep(1000); return 1; } i++; } return 0; } //主函数 int main() { unsigned int i, j, k = 0, n = 0; int flag = 0; string st, keyword; string alpha("abcdefghijklmnopqrstuvwxyz"); string key(20, '\0'); string rule(50, '\0'); system("color 2F"); do { fflush(stdin); system("cls"); cout << "-------------Keyword cipher(Encryption)------------" << endl; cout << "Please enter the plaintext:" << endl; cout << " Plaintext: "; cin >> st; flag = Check(st); } while (flag); do { //输入keyword fflush(stdin); cout << endl << "Select a keyword: "; cin >> keyword; flag = Check(keyword); } while (flag); for (i = 0; i < keyword.length(); i++) { //提取key flag = 1; for (j = 0; j < i; j++) { if (key[j] == keyword[i]) flag = 0; } if (flag) key[k++] = keyword[i]; } key[k] = '\0'; //组合对应表 while (key[n] != '\0') { rule[n] = key[n]; n++; } rule[n] = '\0'; for (i = 0; i < alpha.length(); i++) { flag = 1; for (j = 0; j < key.length(); j++) { if (alpha[i] == key[j]) { flag = 0; break; } } if (flag) rule[n++] = alpha[i]; } rule[n] = '\0'; cout << " Key: " << key << endl; cout << endl << " Password Table" << endl; cout << "---------------------------------------" << endl; cout << "plaintext: " << alpha << endl; cout << "ciphertext: " << rule << endl; cout << "---------------------------------------" << endl << endl; cout << "Ciphertext: "; for (i = 0; i < st.length(); i++) { if (st[i] >= 'a'&&st[i] <= 'z') { cout << rule[(int)(st[i] - 'a')]; } else { cout << rule[(int)(st[i] - 'A')]; } } cout << endl << endl; } |
解密代码与加密代码几乎一致,只需在加密代码的基础上修改小部分内容即可实现。
解密代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#include<iostream> #include<string> #include<stdlib.h> #include<windows.h> using namespace std; int Check(string s) { //检查输入的字符串是否为纯英文 int i = 0; while (s[i] != '\0') { if (!((s[i] >= 'a'&&s[i] <= 'z') || (s[i] >= 'A'&&s[i] <= 'Z'))) { cout << "Error!Please enter again!" << endl; Sleep(1000); return 1; } i++; } return 0; } //主函数 int main() { unsigned int i, j, k = 0, n = 0; int flag = 0; string st, keyword; string alpha("abcdefghijklmnopqrstuvwxyz"); string key(20, '\0'); string rule(50, '\0'); system("color 2F"); do { fflush(stdin); system("cls"); cout << "-------------Keyword cipher(Decryption)------------" << endl; cout << "Please enter the ciphertext:" << endl; cout << " Ciphertext: "; cin >> st; flag = Check(st); } while (flag); do { fflush(stdin); cout << endl << "Enter the keyword: "; cin >> keyword; flag = Check(keyword); } while (flag); for (i = 0; i < keyword.length(); i++) { flag = 1; for (j = 0; j < i; j++) { if (key[j] == keyword[i]) flag = 0; } if (flag) key[k++] = keyword[i]; } key[k] = '\0'; while (key[n] != '\0') { rule[n] = key[n]; n++; } rule[n] = '\0'; for (i = 0; i < alpha.length(); i++) { flag = 1; for (j = 0; j < key.length(); j++) { if (alpha[i] == key[j]) { flag = 0; break; } } if (flag) rule[n++] = alpha[i]; } rule[n] = '\0'; cout << " Key: " << key << endl; cout << endl << " Password Table" << endl; cout << "---------------------------------------" << endl; cout << "plaintext: " << alpha << endl; cout << "ciphertext: " << rule << endl; cout << "---------------------------------------" << endl << endl; cout << "Plaintext: "; for (i = 0; i < st.length(); i++) { if (st[i] >= 'a'&&st[i] <= 'z') { cout << alpha[rule.find(st[i])]; } else { cout << alpha[rule.find(st[i] + 32)]; } } cout << endl << endl; } |
(编译运行环境:Microsoft Visual Studio Community 2017)
没有人 嘻嘻 自己回复自己一下^_^
写的很好,让我康明白了。感谢博主
词频分析可以对于长关键字嘛?
不是觉厉。