Playfair棋盘密码:

  • 加密:
  • 解密


加密:

第一步:制表
密码表共5行5列,第一行(或第一列)是密钥,其余按照字母顺序。密钥中若有重复字母,则可将后面重复的字母去掉。同时i和j会被当作一个字母。
第二步:整理明文
将明文每两个字母组成一对。如果成对后有两个相同字母紧挨或最后一个字母是单个的,就插入一个字母X(或者Q)。
第三步:加密
首先将明文字母两两一组进行切分,并按照如下规则进行加密:

1)若两个字母不同行也不同列,则需要在矩阵中找到另外两个字母(第一个字母对应行优先)。使这四个字母成为一个长方形的四个角。

2)若两个字母同行,则取这两个字母右方的字母(若字母在最右方则取最左方的字母)。

3)若两个字母同列,则取这两个字母下方的字母(若字母在最下方则取最上方的字母)。

解密

第一步同加密的第一步。

第二步:解密
首先将密文字母两两一组进行切分,并按照如下规则进行加密:

1)若两个字母不同行也不同列,则需要在矩阵中找到另外两个字母(第一个字母对应行优先)。使这四个字母成为一个长方形的四个角。

2)若两个字母同行,则取这两个字母左方的字母(若字母在最左方则取最右方的字母)。

3)若两个字母同列,则取这两个字母上方的字母(若字母在最上方则取最下方的字母)。

解密脚本:

#制表(采用横向制表)
def chess_map(k):
    map_k = ''
    alp = 'abcdefghiklmnopqrstuvwxyz' #i j视为同一个字母,j去除
    for i in k:
        if i not in map_k:
            map_k += i
    for i in alp:
        if i not in map_k:
            map_k += i
    s = []
    for i in range(0,len(map_k),5):
        s.append(map_k[i:i+5])
    return s

#解密
def playfair_decode(c,k):
    temp = ''
    for i in k:
        for j in i:
            temp += j
    dex = ''
    for i in c:
        x = temp.index(i)//5
        y = temp.index(i)%5
        dex += str(x)+ str(y)
    m = ''
    for i in range(0,len(dex),4):
        if dex[i] ==dex[i+2]:#同行
            m += k[int(dex[i])][(int(dex[i+1])-1)%5]+k[int(dex[i+2])][(int(dex[i+3])-1)%5]
            #以第一个字母对应的明文优先    
        elif dex[i+1] == dex[i+3]:#同列
            m += k[(int(dex[i])-1)%5][int(dex[i+1])]+k[(int(dex[i+2])-1)%5][int(dex[i+3])]
            #以第一个字母对应的明文优先
        else:
            m += k[int(dex[i])][int(dex[i+3])]+k[int(dex[i+2])][int(dex[i+1])]
            #以第一个字母对应的行优先
        #出现两个字母相同的,即同行同列的怎么办???
    return m

key = chess_map('playfair'.lower())#密钥
c = 'lswpigtqtklbsZ'.lower()#密文
print(playfair_decode(c,key))