我把加密與解碼的原代碼放在這裡
注意:加密已成功,解碼還還存在問題,問題應該出在求逆向矩陣上,我也不想做了,有意者拿去做一下吧。
// 希爾演算法的加密與解密<br />#include <stdio.h><br />#include <string.h><br />#include <stdlib.h><br />#include <math.h><br />#include <conio.h><br />#include <ctype.h><br />#include <memory.h></p><p>// nDime為全部變數,可逆矩陣的維數<br />int nDime = 3;<br />int index = 0;</p><p>// MAXN為明文的最大長度<br />const int MAXN = 256;</p><p>// 矩陣相乘,a是一個列為1的矩陣<br />void MultiplyMatrix(int a[], int b[][10], int *text)<br />{<br />int i, j, t;</p><p>for (i = 0; i < nDime; i++)<br />{<br />t = 0;<br />for (j = 0;j < nDime; j++)<br />t += b[i][j] * a[j];<br />text[index++] = t;<br />}<br />}</p><p>// 求行列式的值<br />int determinant(int a[][10], int size)<br />{<br />int i, j, m, n, s, t, k = 1;<br />int f = 1, c,x, sn;</p><p>for (i = 0, j = 0; i < size && j < size; i++, j++)<br />{<br />if (!a[i][j])<br />{<br />for (m = i; !a[m][j]; m++)<br />{<br />if (m == size)<br />{<br />sn = 0;<br />return sn;<br />}<br />else<br />{<br />for (n = j; n < size; n++)<br />{<br />c = a[i][n];<br />a[i][n] = a[m][n];<br />a[m][n] = c;<br />}<br />}<br />}<br />k *= -1;</p><p>}<br />for (s = size - 1; s > i; s--)<br />{<br />x = a[s][j];<br />for (t = j; t < size; t++)<br />a[s][t] -= a[i][t] * (x / a[i][j]);<br />}<br />}<br />for (i = 0; i < size; i++)<br />f *= a[i][j];<br />sn = k * f;</p><p>return sn;<br />}</p><p>// 求矩陣中某一元素的代數餘子式<br />int func(int matrix[][10], const int i, const int j)<br />{<br />int row, column, m, n;<br />int NewMatrix[10][10];</p><p>for (m = 0, row = 0; row < nDime; row++)<br />{<br />if (i == row)<br />continue;<br />for (column = 0, n = 0; column < nDime; column++)<br />{<br />if (j == column)<br />continue;<br />NewMatrix[m][n++] = matrix[row][column];<br />}<br />m++;<br />}</p><p>int sign = (!((i + j) % 2)) ? 1 : -1;<br />return sign * determinant(NewMatrix, nDime - 1);<br />}</p><p>// 對矩陣求逆,cm矩陣與m矩陣互逆<br />void ConverseMatrix(int m[][10], int cm[][10])<br />{<br />// 矩陣求逆,利用數學公式A(逆)= (1 / |A|)乘以A*<br />// 其中,|A|表示行列式A的值,而A*表示矩陣A的伴隨矩陣<br />int row, column;<br />int StarMat[10][10];// StarMat表示m的伴隨矩陣<br />int t;</p><p>// 初始化伴隨矩陣<br />for (row = 0; row < 10; row++)<br />for (column = 0; column < 10; column++)<br />StarMat[row][column] = 0;</p><p>// 求伴隨矩陣<br />for (row = 0; row < nDime; row++)<br />for (column = 0; column < nDime; column++)<br />{<br />StarMat[row][column] = func(m, row, column);<br />}</p><p>// 求行列式的值<br />t = determinant(m, nDime);</p><p>// 求出逆向矩陣<br />for (row = 0; row < nDime; row++)<br />for (column = 0; column < nDime; column++)<br />cm[row][column] = StarMat[row][column] / t;<br />}</p><p>// 希爾加密及解密演算法<br />// status共兩種狀態,DECRYPT為解密,ENCRYPT為加密<br />void ShellPassword(int *OText, int TextLen, int matrix[][10], int *text)<br />{<br />int i, j, n, a[10];</p><p>// 判斷要將OText分成幾部分<br />n = TextLen / nDime;<br />if (TextLen % nDime)<br />n++;</p><p>// 矩陣相乘<br />// 將OText分成的幾部分分別與matrix矩陣相乘<br />for (i = 0; i < n; i++)<br />{<br />for (j = 0; j < 10; j++)<br />a[j] = 0;<br />for (j = 0; j < nDime; j++)<br />a[j] = OText[i * nDime + j];<br />MultiplyMatrix(a, matrix, text);<br />}<br />}</p><p>int main(void)<br />{<br />int i, temp, row, column;<br />// matrix存放加密或解密矩陣,Password為加密後的結果<br />// OText存放原文轉換為普通數字,如A~1,Z~26<br />int matrix[10][10], ConMatrix[10][10], OText[MAXN], Password[MAXN], OriText[MAXN];<br />char text[MAXN];<br />char sel;</p><p>printf("=================================================/n");<br />putchar('/n');<br />printf(" SHELL加密解密器/n");<br />putchar('/n');<br />printf("=================================================/n");</p><p>while (1)<br />{<br />// 初始化矩陣<br />for (row = 0; row < 10; row++)<br />for (column = 0; column < 10; column++)<br />matrix[row][column] = 0;</p><p>putchar('/n');<br />printf("1.加密/n");<br />printf("2.解密/n");<br />printf("0.退出/n");<br />printf("請輸入你的選擇:/n");<br />sel = getche();</p><p>switch (sel)<br />{<br />case '1':<br />printf("/n請輸入原文:/n");<br />memset(text, '/0', sizeof(text) / sizeof(char));<br />memset(Password, 0, sizeof(Password) / sizeof(int));<br />gets(text);</p><p>printf("輸入加密矩陣的維數,維數不能超過10維:/n");<br />scanf("%d", &nDime);<br />printf("輸入矩陣,該矩陣必須為可逆矩陣,否則將不能進行解密:/n");<br />// 可逆矩陣即,設A為n階矩陣,如果存n在階矩陣B使得AB=BA=1<br />// 則矩陣A是可逆的,稱B是A的逆矩陣<br />for (row = 0; row < nDime; row++)<br />for (column = 0; column < nDime; column++)<br />scanf("%d", &matrix[row][column]);<br />// 將小寫字母轉換為大寫字母<br />for (i = 0; text[i] != '/0'; i++)<br />if (islower(text[i]))<br />text[i] |= 0x20;<br />// OText存放將字母轉換為相應數,如A~1,Z~26<br />for (i = 0; i < MAXN; i++)<br />OText[i] = 0;<br />for (i = 0; text[i] != '/0'; i++)<br />OText[i] = text[i] - 'A' + 1;<br />// 加密<br />ShellPassword(OText, strlen(text), matrix, Password);<br />// 將加密後的內容列印出來<br />printf("加密後的內容為:/n");<br />for (i = 0; i < strlen(text); i++)<br />printf("%d ", Password[i]);<br />putchar('/n');<br />break;<br />case '2':<br />printf("/n請輸入密文,以英文字元結束輸入(如12 13 81 a):/n");<br />for (i = 0; i < MAXN; i++)<br />{<br />if (1 == scanf("%d", &temp))<br />Password[i] = temp;<br />else<br />break;<br />}<br />// 吸收多餘的字元<br />while (getchar() != '/n')<br />;<br />// 加密矩陣<br />printf("請輸入解密矩陣的維數:/n");<br />scanf("%d", &nDime);<br />printf("請輸入解密矩陣:/n");<br />for (row = 0; row < nDime; row++)<br />for (column = 0; column < nDime; column++)<br />scanf("%d", &matrix[row][column]);<br />// 求出解密矩陣的逆矩陣,將matrix轉置的結果存到ConMatrix中<br />ConverseMatrix(matrix, ConMatrix);<br />// 解密<br />memset(OriText, 0, sizeof(OriText) / sizeof(int));<br />// Password是得到的密碼,ConMatrix為逆向矩陣<br />ShellPassword(Password, i, ConMatrix, OriText);<br />// 列印出解密後的內容<br />printf("解密後的內容為:/n");<br />for (int j = 0; j < i; j++)<br />printf("%c ", OriText[j] + 'A' - 1);<br />putchar('/n');<br />break;<br />case '0':<br />return 0;<br />default:<br />break;<br />}<br />getchar();<br />}</p><p>return 0;<br />}