#include <bits/stdc++.h>
using namespace std;
typedef struct{
int row;
int col;
}position; //矩阵中位置
char KeyMat[5][5]; // 密钥矩阵
//由密钥生成矩阵
void generateMatrix(string key)
{
int flag[26] = {0}; //记录是否重复
int x = 0, y = 0;
//将key值填入矩阵
for(int i=0; i<key.length(); i++)
{
if(key[i] == 'j') key[i] = 'i'; // 用 i 代替 j
if(flag[key[i]-'a'] == 0) //只有未出现的字母,flag=0
{
KeyMat[x][y++] = key[i]; //写入矩阵
flag[key[i]-'a'] = 1; //记录该字母已出现
}
if(y==5) x++, y=0; //每行五个字母
}
//填剩余字母
for(char ch = 'a'; ch <= 'z'; ch++)
{
if(ch == 'j') continue; //跳过j
if(flag[ch - 'a'] == 0)
{
KeyMat[x][y++] = ch;
flag[ch - 'a'] = 1 ;
}
if(y==5) x++, y=0;
}
}
//填充不相关字母 x
string formatMessage(string msg)
{
for (int i = 0; i < msg.length(); i++) //将j换为i
{
if (msg[i] == 'j') msg[i] = 'i';
}
for(int ii=1; ii<msg.length(); ii+=2) //比较
{
if (msg[ii - 1] == msg[ii]) msg.insert(ii, "x"); //若相邻元素相同,填充x
}
if(msg.length()%2 != 0) msg += "x"; //若明文总数为奇数,填充x
return msg;
}
//返回字符再矩阵中的位置
position getPosition(char c)
{
for(int i=0; i<5; i++)
for(int j=0; j<5; j++)
if(c == KeyMat[i][j])
{
position p = {i, j};
return p;
}
}
//加密
string encrypt(string message)
{
string ctext = "";
for(int i=0; i<message.length(); i+=2) // i+2,成对加密
{
position p1 = getPosition(message[i]);
position p2 = getPosition(message[i+1]);
int x1 = p1.row; int y1 = p1.col;
int x2 = p2.row; int y2 = p2.col;
if( x1 == x2 ) //同行:右移
{
ctext += KeyMat[x1][(y1+1)%5];
ctext += KeyMat[x2][(y2+1)%5];
}
else if( y1 == y2 ) // 同列:下移
{
ctext += KeyMat[ (x1+1)%5 ][ y1 ];
ctext += KeyMat[ (x2+1)%5 ][ y2 ];
}
else //不同行同列,取交叉元素
{
ctext += KeyMat[ x1 ][ y2 ];
ctext += KeyMat[ x2 ][ y1 ];
}
}
return ctext;
}
//解密
string Decrypt(string message)
{
string ptext = "";
for(int i=0; i<message.length(); i+=2) // 成对解密
{
position p1 = getPosition(message[i]);
position p2 = getPosition(message[i+1]);
int x1 = p1.row; int y1 = p1.col;
int x2 = p2.row; int y2 = p2.col;
if( x1 == x2 ) // 同行:左移
{
ptext += KeyMat[x1][ --y1<0 ? 4: y1 ];
ptext += KeyMat[x2][ --y2<0 ? 4: y2 ];
}
else if( y1 == y2 ) // 同列:上移
{
ptext += KeyMat[ --x1<0 ? 4: x1 ][y1];
ptext += KeyMat[ --x2<0 ? 4: x2 ][y2];
}
else
{
ptext += KeyMat[ x1 ][ y2 ];
ptext += KeyMat[ x2 ][ y1 ];
}
}
return ptext;
}
int main()
{
string x;
string plaintext;
cout << "输入明文 : ";
cin >> plaintext; //储存明文
string key="qazwsxedcrfvtgbyhnujmikolp"; //密钥
for (int i = 0; i < key.length(); i++)
{
generateMatrix(key); //生成密钥矩阵
}
cout << "密钥矩阵: " << endl;
for (int k = 0; k < 5; k++)
{
for (int j = 0; j < 5; j++)
{
cout << KeyMat[k][j] << " ";
}
cout << endl;
}
cout << "明文: \t\t: " << plaintext << endl;
string fmsg = formatMessage(plaintext);
cout << "填充后的明文 \t: " << fmsg << endl;
string ciphertext = encrypt(fmsg);
cout << "加密后的密文: \t: " << ciphertext << endl;
string decryptmsg = Decrypt(ciphertext);
cout<< "解密后为: \t: " << decryptmsg << endl;
}