列置换密码原理:Column Permutation Cipher属于置换密码的一种,其加密过程大致如下:把明文按某一顺序排列成一个矩阵,其中不足部分用符号Φ填充。然后按另一顺序选出矩阵中的字母以形成密文,最后截成固定长度的字母组成密文。由加密过程可知,改变矩阵的大小和选出顺序可以得到不同形式的密码。
编程实现思路:要实现Column Permutation Cipher的加密/解密,关键是构造明文/密文矩阵并能够得到一个合适的选出规则。在编程中通过输入一串英文字符来完成以上操作,具体步骤为:首先选用一串英文字符作为密钥,构造的矩阵的列数与字符串长度保持一致,明文/密文的长度不足以构造矩阵的则用Φ填充。按照字母的字典顺序给密钥字母编号,对于重复的字母,谁的位置靠前,谁的编号就靠前。于是我们就得到一组与密钥词语对应的数字序列。最后据此数字序列中的数字顺序按列选出明文/密文。
程序流程图:
加密代码实现:
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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
#include <iostream> #include <string> #include <string.h> #include <unistd.h> using namespace std; struct group { char ch = '\0'; int num = -1; }; 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; return 1; } i++; } return 0; } //处理密钥,返回指针数组 int *wordKey(string key, int k[20]) { int i, j; // int k[20] = { 0 }; int *p = k; int flag = 0; char temp1; char tem[20] = { 0 }; char keygroup[20] = { 0 }; for (i = 0; i < key.length(); i++) {//设置临时数组 keygroup[i] = key[i]; } //冒泡排序 for (i = 0; i < key.length(); i++) { flag = 0; for (j = 0; j < key.length() - i - 1; j++) { if (keygroup[j] > keygroup[j + 1]) { temp1 = keygroup[j]; keygroup[j] = keygroup[j + 1]; keygroup[j + 1] = temp1; flag = 1; } } if (flag == 0) break; } //设置临时数组 for (i = 0; i < key.length(); i++) { tem[i] = keygroup[i]; } //对应的密钥顺序 cout << endl << "key = (d, f)" << endl; cout << "d = " << key.length() << " "; cout << "f = ("; for (i = 0; i < key.length(); i++) { for (j = 0; j < key.length(); j++) { if (keygroup[j] == key[i] && tem[j] != '#') { k[i] = j + 1; tem[j] = '#'; cout << " " << k[i]; break; } } } cout << " )" << endl << endl; return p; } int main(){ int flag = 0; int k[20] = { 0 }; int t, i, j, m, n; string st, key; char tem[50] = { 0 }; char cipher[10][10] = { 0 }; int *p; do { fflush(stdin); cout << "--------Column Permutation cipher(Encryption)--------" << endl; cout << " the null letter is 'x' " << endl; cout << "Please enter the plaintext:"; cin >> st; flag = Check(st); } while (flag); do { //输入key fflush(stdin); cout << "Please enter the key: "; cin >> key; flag = Check(key); } while (flag); //明文不是key的整数倍补'x' t = st.length(); if (t%key.length() != 0) t = ((t / (key.length()) + 1)*key.length()); for (i = 0; i < t; i++) { if (i < st.length()) tem[i] = st[i]; else tem[i] = 'x'; } //打印plain matrix cout << "Plaintext Matrix" << endl << endl; m = 0; n = (strlen(tem)) / (key.length()); for (i = 0; i < n; i++) { for (j = 0; j < key.length(); j++) { cipher[i][j] = tem[m]; cout << " " << cipher[i][j]; m++; } cout << endl; } p = wordKey(key, k); //加密 cout << "CipherText:"; //cout << key.length() << " " << n << endl; for (i = 0; i < key.length(); i++) { for (j = 0; j < n; j++) { cout << cipher[j][(p[i] - 1)]; } } 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
#include <iostream> #include <string> #include <string.h> #include <unistd.h> using namespace std; struct group { char ch = '\0'; int num = -1; }; 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; return 1; } i++; } return 0; } //处理密钥,返回指针数组 int *wordKey(string key, int k[20]) { int i, j; // int k[20] = { 0 }; int *p = k; int flag = 0; char temp1; char tem[20] = { 0 }; char keygroup[20] = { 0 }; for (i = 0; i < key.length(); i++) {//设置临时数组 keygroup[i] = key[i]; } //冒泡排序 for (i = 0; i < key.length(); i++) { flag = 0; for (j = 0; j < key.length() - i - 1; j++) { if (keygroup[j] > keygroup[j + 1]) { temp1 = keygroup[j]; keygroup[j] = keygroup[j + 1]; keygroup[j + 1] = temp1; flag = 1; } } if (flag == 0) break; } //设置临时数组 for (i = 0; i < key.length(); i++) { tem[i] = keygroup[i]; } //对应的密钥顺序 cout << endl << "key = (d, f)" << endl; cout << "d = " << key.length() << " "; cout << "f = ("; for (i = 0; i < key.length(); i++) { for (j = 0; j < key.length(); j++) { if (keygroup[j] == key[i] && tem[j] != '#') { k[i] = j + 1; tem[j] = '#'; cout << " " << k[i]; break; } } } cout << " )" << endl << endl; return p; } int main(){ int flag = 0; int k[20] = { 0 }; int i, j, m, n; string st, key; char tem[50] = { 0 }; char plain[10][10] = { 0 }; int *p; do { fflush(stdin); cout << "--------Column Permutation cipher(Decryption)--------" << endl; cout << "Please enter the ciphertext:"; cin >> st; flag = Check(st); } while (flag); do { //输入key fflush(stdin); cout << "Please enter the key: "; cin >> key; flag = Check(key); } while (flag); //判断是否符合要求 if (((st.length()) % (key.length())) != 0) { cout << endl << "Error!The length of the ciphertext must be an integral multiple of the length of the key!" << endl << endl; exit(-1); } p = wordKey(key, k); //组建明文序列 m = 0; n = (st.length()) / (key.length()); for (i = 0; i < key.length(); i++) { for (j = 0; j < n; j++) { plain[j][(p[i] - 1)] = st[m]; m++; } } //打印plain matrix cout << "Plaintext Matrix" << endl << endl; for (i = 0; i < n; i++) { for (j = 0; j < key.length(); j++) { cout << " " << plain[i][j]; } cout << endl; } cout << endl; //输出明文 cout << "Plaintext:"; for (i = 0; i < n; i++) { for (j = 0; j < key.length(); j++) { cout << plain[i][j]; } } cout << endl << endl; } |
思考:
1. Column permutation cipher 的原理是什么?
答:Column Permutation Cipher属于置换密码的一种,其原理如下:把明文按行填充排列成一个矩阵,其中不足部分用符号Φ填充。然后按预定顺序按列读取形成密文。
2. 给定关键字为“experiment”,加密矩阵将包括几列,以及列置换的次序是什么?
答:加密矩阵将包括10列,列置换次序为:1-10-7-2-8-4-5-3-6-9.
3. Column permutation cipher的安全性增强方法是什么?
答:进行双重换位加密。先用列换位法将明文加密,然后再次利用列换位法将第一次换位加密的密文加密。经过两次换位后,明文字母的位置完全被打乱了,从而可以增强安全性。
(编译运行环境:g++ [Debian 7.3.0-19] 7.3.0)
说点什么