列表

详情


NC207928. playfair

描述

用playfair加密信息。加密过程中的j都由i来代替playfair加密算法首先需要绘制密码表,密码表是一个5*5的矩阵,开始由密钥按顺序排列,其余按照未出现的字母顺序。若密钥中含有重复字母需要将重复字母去掉,若有j用i来代替,例如密钥为nowcoder,得到的密码表为

加密明文需要符合以下规则:
  1. 将明文中每两个字母组成一对,若成对后是两个相同字母或留下一个字母无法成对,则不进行变化直接放入密文中
  2. 明文对p1p2在同一行,对应密文对c1c2分别为紧靠p1p2右端的字母,最后一列右端对应第一列。例如明文对为rf,对应密文对为ae
  3. 明文对p1p2在同一列,对应密文对c1c2分别为紧靠p1p2下方的字母,最后一行下方对应第一行。例如明文对为rv,对应密文对为ho
  4. 明文对p1p2不在同一行且不在同一列,对应密文对c1c2分别为p1p2确定的矩形中的同行另外两角,例如明文对为hb,对应密文对为kr
求密文是什么吗?

输入描述

,输入保证都为小写字母

示例1

输入:

"nowcoder","iloveyou"

输出:

"kgrobunv"

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python3(3.5.2) 解法, 执行用时: 32ms, 内存消耗: 6520K, 提交时间: 2020-08-01 21:34:32

#
# playfair加密算法
# @param key string字符串 密钥
# @param str string字符串 明文
# @return string字符串
#
class Solution:
    def Encode(self , key , s ):
        # write code here
        table = [[None for j in range(5)] for i in range(5)]
        visited = set()
        i = 0
        for char in key:
            if char == 'j':
                char = 'i'
            if char in visited:
                continue
            visited.add(char)
            table[i // 5][i % 5] = char
            i += 1
        cur = ord('a')
        while i < 25:
            while chr(cur) in visited or chr(cur) == 'j':
                cur += 1
            table[i // 5][i % 5] = chr(cur)
            cur += 1
            i += 1

        res = ""
        n = len(s)
        s = s.replace('j', 'i')
        for i in range(0, n, 2):
            if i == n - 1 or s[i] == s[i+1]:
                res += s[i:i+2]
                continue
            for j in range(5):
                for k in range(5):
                    if table[j][k] == s[i]:
                        x1, y1 = j,k
                    elif table[j][k] == s[i+1]:
                        x2, y2 = j,k
            if x1 == x2:
                res += table[x1][(y1+1)%5] + table[x2][(y2+1)%5]
            elif y1 == y2:
                res += table[(x1+1)%5][y1] + table[(x2+1)%5][y2]
            else:
                res += table[x1][y2] + table[x2][y1]
        return res

Java(javac 1.8) 解法, 执行用时: 12ms, 内存消耗: 11412K, 提交时间: 2020-08-01 22:26:39

import java.util.*;

public class Solution {
    /**
     * playfair加密算法
     * @param key string字符串 密钥
     * @param str string字符串 明文
     * @return string字符串
     */
    public String Encode (String key, String str) {
        // write code here
        char[] map = new char[25];
        int[] index=new int[26];
        Arrays.fill(index,-1);
        char[] ss=str.toCharArray();
        //加密
        int ptr=0;
        for(char c:(key+"abcdefghijklmnopqrstuvwxyz").toCharArray()){
            if(c=='j')c='i';
            if(index[c-'a']==-1){
                map[ptr]=c;
                index[c-'a']=ptr++;
            }
        }
        //加密

        for(int i=0,j=1;j<ss.length;i+=2,j+=2){
            if(ss[i]=='j')ss[i]='i';
            if(ss[j]=='j')ss[j]='i';
            if(ss[i]==ss[j])continue;
            int a=index[ss[i]-'a'],b=index[ss[j]-'a'];
            int x1=a/5,y1=a%5,x2=b/5,y2=b%5;
            if(x1==x2){
                y1=(y1+1)%5;
                y2=(y2+1)%5;
            }
            else if(y1==y2){
                x1=(x1+1)%5;
                x2=(x2+1)%5;
            }
            else{
                //交换纵坐标
                int temp=y1;y1=y2;y2=temp;
            }
            ss[i]=map[x1*5+y1];
            ss[j]=map[x2*5+y2];
        }
        return new String(ss);
    }


}

Python(2.7.3) 解法, 执行用时: 25ms, 内存消耗: 5760K, 提交时间: 2020-08-01 21:35:33

#
# playfair加密算法
# @param key string字符串 密钥
# @param str string字符串 明文
# @return string字符串
#
class Solution:

    def Encode(self, key, s):
        n = len(s)
        res = []
        s = s.replace('j', 'i')
        key = key.replace('j', 'i')
        d = {}
        for c in key + 'abcdefghiklmnopqrstuvwxyz':
            if c in d: continue
            d[c] = len(d)
        L = ['a'] * 26
        for c in d:
            L[d[c]] = c

        for i in xrange(0, n, 2):
            if i + 1 >= n: break
            if s[i] == s[i + 1]:
                res += s[i] + s[i + 1]
                continue
            x1, y1 = d[s[i]] / 5, d[s[i]] % 5
            x2, y2 = d[s[i + 1]] / 5, d[s[i + 1]] % 5
            if x1 == x2:
                y1 = (y1 + 1) % 5
                y2 = (y2 + 1) % 5
            elif y1 == y2:
                x1 = (x1 + 1) % 5
                x2 = (x2 + 1) % 5
            else:
                # x1, x2 = x2, x1
                y1, y2 = y2, y1
            res.append(L[x1 * 5 + y1])
            res.append(L[x2 * 5 + y2])
        if n % 2:
            res += s[-1]
        return ''.join(res)
                

C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 508K, 提交时间: 2020-08-09 18:57:25

class Solution
{
	public:
		char s[5][5];
		int vs[26];
		void find(char ch,int &x,int &y)
		{
			for(int i=0;i<5;i++)
			for(int j=0;j<5;j++)
			{
				if(s[i][j]==ch)
				{
					x=i;
					y=j;
					return;
				}
			}
		}
		string Encode(string key,string str)
		{
			for(int i=0;i<26;i++)
			key+=char('a'+i),vs[i]=0;
			int x,y,c=0;
			for(int i=0;i<key.size();i++)
			{
				if(key[i]=='j')
				key[i]='i';
				if(vs[key[i]-'a'])
				continue;
				vs[key[i]-'a']=1;
				x=c/5;
				y=c%5;
				c++;
				s[x][y]=key[i];
			 } 
			 int x1,x2,y1,y2,r=str.size();
			 if(r%2)
			 r--;
			 for(int i=0;i<r;i+=2)
			 {
			 	if(str[i]=='j')
			 	str[i]='i';
			 	if(str[i+1]=='j')
			 	str[i+1]='i';
			 	if(str[i]==str[i+1])
			 	continue;
			 	find(str[i],x1,y1);
			 	find(str[i+1],x2,y2);
			 	if(x1==x2)
			 	y1=(y1+1)%5,y2=(y2+1)%5;
			 	else if(y1==y2)
			 	x1=(x1+1)%5,x2=(x2+1)%5;
			 	else
			 	{
			 		swap(y1,y2);
				 }
				 str[i]=s[x1][y1];
				 str[i+1]=s[x2][y2];
				 
			 }
			 if(str.size()%2&&str[r]=='j')
			 str[r]='i';
			 return str;
		}
};

上一题