1. 程式人生 > >古典密碼(凱撒密碼/維吉尼亞密碼/Play fair密碼/Hill密碼)的實現(MFC介面)

古典密碼(凱撒密碼/維吉尼亞密碼/Play fair密碼/Hill密碼)的實現(MFC介面)

void CEn_DeDlg::random_Matrix() { int i, j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { K[i][j] = rand() % 26; //產生一個5*5模26的矩陣 } } } //求矩陣的行列式 int CEn_DeDlg::Det(int matrix[5][5], int row) { int i, j; int cofa[5][5]; //用於存放餘子陣
int l; //l為所遞迴的餘子陣的行 int p = 0, q = 0; int sum = 0; //由於行和列相同(方陣),所以行列式的值一定存在,故不需要判斷是否為方陣 //遞迴基 if (row == 1) return matrix[0][0]; for (i = 0; i < row; i++) { for (l = 0; l < row - 1; l++) { if (l < i) p = 0; else
p = 1; for (j = 0; j< row - 1; j++) { cofa[l][j] = matrix[l + p][j + 1]; } } //相當於(-1)^i if (i % 2 == 0) q = 1; else q = (-1); sum = sum + matrix[i][0] * q * Det(cofa, row - 1
); } return sum; } //求兩個數的最大公約數 int CEn_DeDlg::gcd(int a, int b) { int temp; //交換兩個數的大小,使得a為較大數 if (a < b) { temp = a; a = b; b = temp; } while (a % b) { temp = b; b = a % b; a = temp; } return b; } /* *判斷矩陣K是否在模26的情況下可逆 *因為矩陣在模26的情形下存在可逆矩陣的充分必要條件是 *gcd(det K,26) = 1 */ bool CEn_DeDlg::Inverse(int matrix[5][5]) { if (gcd(Det(matrix, ROW), M) == 1) return true; else return false; } void CEn_DeDlg::multiphy(int matrix[5][5], int p[5], int row) { int i, j; //先將密文單元清零 memset(C, 0, sizeof(C)); for (i = 0; i < ROW; i++) { for (j = 0; j < ROW; j++) { C[i] += P[j] * K[j][i]; } } } //將明文加密為密文 CString CEn_DeDlg::encryption(CString plaintext) { int i; CString ciphertext; //將字串轉化為明文陣列 for (i = 0; i < ROW; i++) { P[i] = plaintext[i] - 'a'; } multiphy(K, P, ROW); //將密文陣列轉化為密文 for (i = 0; i < ROW; i++) //這裡先將其模26,再翻譯為對應的字母 { C[i] = Mod(C[i]); ciphertext.AppendChar(C[i] + 'A'); } return ciphertext; } //求出伴隨矩陣 void CEn_DeDlg::adjoint_matrix(int matrix[5][5], int row) { int i, j, k, l; int p, q; p = q = 0; int temp[5][5]; for (i = 0; i < ROW; i++) { for (j = 0; j < ROW; j++) { for (k = 0; k < ROW - 1; k++) { if (k < i) p = 0; else p = 1; for (l = 0; l < ROW - 1; l++) { if (l < j) q = 0; else q = 1; temp[k][l] = matrix[k + p][l + q]; } } D[j][i] = (int)pow(-1, (double)i + j)*Det(temp, ROW - 1); D[j][i] = Mod(D[j][i]); } } } //將密文解密為明文(為了辨識清楚,我們統一以小寫字母作為明文,大寫字母作為密文) CString CEn_DeDlg::deciphering(CString ciphertext) { //求出矩陣的逆 CString text; int determinant = Det(K, ROW); int inver = inverse(determinant, 26); adjoint_matrix(K, ROW); //伴隨矩陣 //cout << "行列式的值: " << determinant << endl; int i, j; memset(F, 0, sizeof(F)); for (i = 0; i < ROW; i++) { for (j = 0; j < ROW; j++) { F[i] += C[j] * D[j][i]; } F[i] *= inver; F[i] = Mod(F[i]); //算到的結果要模去26 } for (i = 0; i < ROW; i++) text.AppendChar(F[i] + 'a'); return text; } GCD CEn_DeDlg::extended_Euclid(int a, int b) { GCD aa, bb; if (b == 0) { aa.x = 1; aa.y = 0; aa.d = a; return aa; } else { bb = extended_Euclid(b, a%b); aa.x = bb.y; aa.y = bb.x - (a / b) * bb.y; aa.d = bb.d; } return aa; } int CEn_DeDlg::inverse(int a, int m) { GCD aa; aa = extended_Euclid(a, m); return aa.x; } int CEn_DeDlg::Mod(int a) { return a >= 0 ? a % M : (M + a % M); }