题目
牛牛用 playfair 加密信息。加密过程中的 都由
来代替。
playfair 加密算法首先需要绘制密码表,密码表是一个 的矩阵,开始由密钥按顺序排列,其余按照未出现的字母顺序。若密钥中含有重复字母需要将重复字母去掉,若有
用
来代替。
加密明文需要符合以下规则:
将明文中每两个字母组成一对,若成对后是两个相同字母或留下一个字母无法成对,则不进行变化直接放入密文中。
明文对 在同一行,对应密文对
分别为紧靠
右端的字母,最后一列右端对应第一列。
明文对 在同一列,对应密文对
分别为紧靠
下方的字母,最后一行下方对应第一行。
明文对 不在同一行且不在同一列,对应密文对
分别为
确定的矩形中的同行另外两角。
现在给定密钥和明文,求出密文是什么吗?
解题思路
根据给定的密钥 绘制密码表。
使用 记录字符在密码表中的位置。使用
记录密码表中每个位置上的字符。
然后按照加密明文规则对明文 求出密文。
注意用字符 替代字符
。
C++代码
class Solution {
public:
/**
* playfair加密算法
* @param key string字符串 密钥
* @param str string字符串 明文
* @return string字符串
*/
string Encode(string key, string str) {
// write code here
int vis[26] = {0};
map<char, pair<int,int>> pos;
vector<vector<char>> matrix(5, vector<char>(5));
int row = 0;
int col = 0;
for(auto c : key){
if(c == 'j')
c = 'i';
int index = c - 'a';
if(!vis[index]){
vis[index] = 1;
pos[c] = make_pair(row, col);
matrix[row][col] = c;
++col;
if(col==5){
col = 0;
++row;
}
}
}
vis['j'-'a'] = 1;
for(int i=0; i<26; ++i){
if(!vis[i]){
char ch = i + 'a';
pos[ch] = make_pair(row, col);
matrix[row][col] = ch;
++col;
if(col==5){
col = 0;
++row;
}
}
}
for(int i=1; i<str.size(); i+=2){
if(str[i-1]=='j') str[i-1]='i';
if(str[i]=='j') str[i]='i';
int c1 = str[i-1];
int c2 = str[i];
if(c1==c2)
continue;
int x1 = pos[c1].first;
int y1 = pos[c1].second;
int x2 = pos[c2].first;
int y2 = pos[c2].second;
if(x1==x2){
y1 = (y1+1)%5;
y2 = (y2+1)%5;
str[i-1] = matrix[x1][y1];
str[i] = matrix[x2][y2];
}
else if(y1==y2){
x1 = (x1+1)%5;
x2 = (x2+1)%5;
str[i-1] = matrix[x1][y1];
str[i] = matrix[x2][y2];
}
else{
str[i-1] = matrix[x1][y2];
str[i] = matrix[x2][y1];
}
}
return str;
}
}; 
京公网安备 11010502036488号