image.png

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. //int key[3][3];
    4. int key[3][3] = {
    5. 17,17,5,
    6. 21,18,21,
    7. 2,2,19
    8. }; //加密密钥
    9. int mod26(int x) //取模
    10. {
    11. return x >= 0 ? (x % 26) : 26 - (abs(x) % 26);
    12. }
    13. /* 求矩阵的|A| */
    14. int findDet(int m[3][3], int n)
    15. {
    16. int det;
    17. if (n == 2) //2阶矩阵
    18. {
    19. det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
    20. }
    21. else if (n == 3) //3阶矩阵
    22. {
    23. det = m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
    24. - m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])
    25. + m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
    26. }
    27. else det = 0; // 无效输入
    28. return mod26(det);
    29. }
    30. int findDetInverse(int R, int D = 26) // R=|A|
    31. {
    32. int i = 0;
    33. int p[100] = { 0,1 };
    34. int q[100] = { 0 }; //商
    35. while (R != 0)
    36. {
    37. q[i] = D / R;
    38. int oldD = D;
    39. D = R;
    40. R = oldD % R;
    41. if (i > 1)
    42. {
    43. p[i] = mod26(p[i - 2] - p[i - 1] * q[i - 2]);
    44. }
    45. i++;
    46. }
    47. if (i == 1)
    48. return 1;
    49. else
    50. return p[i] = mod26(p[i - 2] - p[i - 1] * q[i - 2]);
    51. }
    52. //矩阵乘法
    53. void multiplyMatrices(int a[1000][3], int a_rows, int a_cols, int b[1000][3], int b_rows, int b_cols, int res[1000][3])
    54. {
    55. for (int i = 0; i < a_rows; i++)
    56. {
    57. for (int j = 0; j < b_cols; j++)
    58. {
    59. for (int k = 0; k < b_rows; k++)
    60. {
    61. res[i][j] += a[i][k] * b[k][j];
    62. }
    63. res[i][j] = mod26(res[i][j]);
    64. }
    65. }
    66. }
    67. /* findInverse(输入矩阵 , 阶数 , 输出矩阵) */
    68. //矩阵的逆
    69. void findInverse(int m[3][3], int n, int m_inverse[3][3])
    70. {
    71. int adj[3][3] = { 0 };
    72. int det = findDet(m, n); // key矩阵的行列式
    73. int detInverse = findDetInverse(det);
    74. if (n == 2) //二阶矩阵的逆
    75. {
    76. adj[0][0] = m[1][1];
    77. adj[1][1] = m[0][0];
    78. adj[0][1] = -m[0][1];
    79. adj[1][0] = -m[1][0];
    80. }
    81. else if (n == 3) //三阶矩阵的逆
    82. {
    83. int temp[5][5] = { 0 };
    84. //填充 5x5 矩阵
    85. for (int i = 0; i < 5; i++)
    86. {
    87. for (int j = 0; j < 5; j++)
    88. {
    89. temp[i][j] = m[i % 3][j % 3];
    90. }
    91. }
    92. /* 除第一行和第一列外,沿行乘元素,并沿列放置元素*/
    93. for (int i = 1; i <= 3; i++)
    94. {
    95. for (int j = 1; j <= 3; j++)
    96. {
    97. adj[j - 1][i - 1] = temp[i][j] * temp[i + 1][j + 1] - temp[i][j + 1] * temp[i + 1][j];
    98. }
    99. }
    100. }
    101. for (int i = 0; i < n; i++)
    102. {
    103. for (int j = 0; j < n; j++)
    104. {
    105. m_inverse[i][j] = mod26(adj[i][j] * detInverse);
    106. /* Inverse = (matrix * detInverse) mod 26 */
    107. }
    108. }
    109. }
    110. // C = PK
    111. string encrypt(string pt, int n)
    112. {
    113. int P[1000][3] = { 0 }; // 明文 , 3列矩阵
    114. int C[1000][3] = { 0 }; // 密文
    115. int ptIter = 0;
    116. while (pt.length() % n != 0)
    117. {
    118. pt += "x"; // 用x填补
    119. }
    120. int row = (pt.length()) / n; // P的行数=字母个数/3(n)
    121. for (int i = 0; i < row; i++)
    122. {
    123. for (int j = 0; j < n; j++)
    124. {
    125. P[i][j] = pt[ptIter++] - 'a'; //明文矩阵
    126. }
    127. }
    128. // multiplyMatrices(输入矩阵 , 行数 , 列数 , 密钥, 密钥行数, 密钥列数 , 结果矩阵)
    129. //矩阵乘法
    130. multiplyMatrices(P, row, n, key, n, n, C); // C = PK
    131. string ct = ""; //密文
    132. for (int i = 0; i < row; i++)
    133. {
    134. for (int j = 0; j < n; j++)
    135. {
    136. ct += (C[i][j] + 'a');
    137. }
    138. }
    139. return ct;
    140. }
    141. // P = C*(k_inverse)
    142. string decrypt(string ct, int n)
    143. {
    144. int P[1000][3] = { 0 }; // 明文矩阵
    145. int C[1000][3] = { 0 }; // 密文矩阵
    146. int ctIter = 0;
    147. int row = ct.length() / n; // 密文的行数
    148. for (int i = 0; i < row; i++)
    149. {
    150. for (int j = 0; j < n; j++)
    151. {
    152. C[i][j] = ct[ctIter++] - 'a';
    153. }
    154. }
    155. int k_inverse[3][3] = { 0 }; //密文的逆矩阵
    156. findInverse(key, n, k_inverse);
    157. // P = C*(k_inverse)
    158. multiplyMatrices(C, row, n, k_inverse, n, n, P);
    159. string pt = "";
    160. for (int i = 0; i < row; i++)
    161. {
    162. for (int j = 0; j < n; j++)
    163. {
    164. pt += (P[i][j] + 'a');
    165. }
    166. }
    167. return pt;
    168. }
    169. int main(void)
    170. {
    171. string pt="rlx";
    172. /*cout << "请输入要加密的明文: ";
    173. cin >> pt;*/
    174. /*cout << "请输入加密矩阵的阶数: ";
    175. cin >> n;
    176. cout << "请输入加密矩阵(必须可逆): " << endl;
    177. for (int i = 0; i < n; i++)
    178. {
    179. for (int j = 0; j < n; j++)
    180. {
    181. cin >> key[i][j];
    182. }
    183. }*/
    184. cout << "\n明文 : " << pt << endl;
    185. string ct = encrypt(pt, 3);
    186. cout << "密文 : " << ct << endl;
    187. string dt = decrypt(ct, 3);
    188. cout << "解密t : " << dt << endl;
    189. }