1. #include <bits/stdc++.h>
    2. using namespace std;
    3. typedef struct{
    4. int row;
    5. int col;
    6. }position; //矩阵中位置
    7. char KeyMat[5][5]; // 密钥矩阵
    8. //由密钥生成矩阵
    9. void generateMatrix(string key)
    10. {
    11. int flag[26] = {0}; //记录是否重复
    12. int x = 0, y = 0;
    13. //将key值填入矩阵
    14. for(int i=0; i<key.length(); i++)
    15. {
    16. if(key[i] == 'j') key[i] = 'i'; // 用 i 代替 j
    17. if(flag[key[i]-'a'] == 0) //只有未出现的字母,flag=0
    18. {
    19. KeyMat[x][y++] = key[i]; //写入矩阵
    20. flag[key[i]-'a'] = 1; //记录该字母已出现
    21. }
    22. if(y==5) x++, y=0; //每行五个字母
    23. }
    24. //填剩余字母
    25. for(char ch = 'a'; ch <= 'z'; ch++)
    26. {
    27. if(ch == 'j') continue; //跳过j
    28. if(flag[ch - 'a'] == 0)
    29. {
    30. KeyMat[x][y++] = ch;
    31. flag[ch - 'a'] = 1 ;
    32. }
    33. if(y==5) x++, y=0;
    34. }
    35. }
    36. //填充不相关字母 x
    37. string formatMessage(string msg)
    38. {
    39. for (int i = 0; i < msg.length(); i++) //将j换为i
    40. {
    41. if (msg[i] == 'j') msg[i] = 'i';
    42. }
    43. for(int ii=1; ii<msg.length(); ii+=2) //比较
    44. {
    45. if (msg[ii - 1] == msg[ii]) msg.insert(ii, "x"); //若相邻元素相同,填充x
    46. }
    47. if(msg.length()%2 != 0) msg += "x"; //若明文总数为奇数,填充x
    48. return msg;
    49. }
    50. //返回字符再矩阵中的位置
    51. position getPosition(char c)
    52. {
    53. for(int i=0; i<5; i++)
    54. for(int j=0; j<5; j++)
    55. if(c == KeyMat[i][j])
    56. {
    57. position p = {i, j};
    58. return p;
    59. }
    60. }
    61. //加密
    62. string encrypt(string message)
    63. {
    64. string ctext = "";
    65. for(int i=0; i<message.length(); i+=2) // i+2,成对加密
    66. {
    67. position p1 = getPosition(message[i]);
    68. position p2 = getPosition(message[i+1]);
    69. int x1 = p1.row; int y1 = p1.col;
    70. int x2 = p2.row; int y2 = p2.col;
    71. if( x1 == x2 ) //同行:右移
    72. {
    73. ctext += KeyMat[x1][(y1+1)%5];
    74. ctext += KeyMat[x2][(y2+1)%5];
    75. }
    76. else if( y1 == y2 ) // 同列:下移
    77. {
    78. ctext += KeyMat[ (x1+1)%5 ][ y1 ];
    79. ctext += KeyMat[ (x2+1)%5 ][ y2 ];
    80. }
    81. else //不同行同列,取交叉元素
    82. {
    83. ctext += KeyMat[ x1 ][ y2 ];
    84. ctext += KeyMat[ x2 ][ y1 ];
    85. }
    86. }
    87. return ctext;
    88. }
    89. //解密
    90. string Decrypt(string message)
    91. {
    92. string ptext = "";
    93. for(int i=0; i<message.length(); i+=2) // 成对解密
    94. {
    95. position p1 = getPosition(message[i]);
    96. position p2 = getPosition(message[i+1]);
    97. int x1 = p1.row; int y1 = p1.col;
    98. int x2 = p2.row; int y2 = p2.col;
    99. if( x1 == x2 ) // 同行:左移
    100. {
    101. ptext += KeyMat[x1][ --y1<0 ? 4: y1 ];
    102. ptext += KeyMat[x2][ --y2<0 ? 4: y2 ];
    103. }
    104. else if( y1 == y2 ) // 同列:上移
    105. {
    106. ptext += KeyMat[ --x1<0 ? 4: x1 ][y1];
    107. ptext += KeyMat[ --x2<0 ? 4: x2 ][y2];
    108. }
    109. else
    110. {
    111. ptext += KeyMat[ x1 ][ y2 ];
    112. ptext += KeyMat[ x2 ][ y1 ];
    113. }
    114. }
    115. return ptext;
    116. }
    117. int main()
    118. {
    119. string x;
    120. string plaintext;
    121. cout << "输入明文 : ";
    122. cin >> plaintext; //储存明文
    123. string key="qazwsxedcrfvtgbyhnujmikolp"; //密钥
    124. for (int i = 0; i < key.length(); i++)
    125. {
    126. generateMatrix(key); //生成密钥矩阵
    127. }
    128. cout << "密钥矩阵: " << endl;
    129. for (int k = 0; k < 5; k++)
    130. {
    131. for (int j = 0; j < 5; j++)
    132. {
    133. cout << KeyMat[k][j] << " ";
    134. }
    135. cout << endl;
    136. }
    137. cout << "明文: \t\t: " << plaintext << endl;
    138. string fmsg = formatMessage(plaintext);
    139. cout << "填充后的明文 \t: " << fmsg << endl;
    140. string ciphertext = encrypt(fmsg);
    141. cout << "加密后的密文: \t: " << ciphertext << endl;
    142. string decryptmsg = Decrypt(ciphertext);
    143. cout<< "解密后为: \t: " << decryptmsg << endl;
    144. }