type
Post
status
Published
date
Feb 12, 2022
slug
playfair
summary
playfair
tags
Crypto
CTF
category
CRYPTO
icon
password

playfair

基本原理

Playfair算法基于一个5*5的字母矩阵,该矩阵使用一个关键词构造,方法是按从左到右、从上到下顺序,填入关键词的字母(去除重复字母)后,将字母表其作余字母填入。
例如: 关键词取:monarchy时,字母矩阵为下图如示(矩阵只能放25个字母,I与J同)
notion image

加密规则

Playfair加密算法是先将明文按两个字母一组进行分组,然后在矩阵中找对应的密文。
取密文的规则如下:
1.若明文出现相同字母在一组,则在重复的明文字母中插入一个填充字母(eg:z)进行分隔后重新分组(eg: balloon被重新分组为ba lz lo on)
2.若分组到最后一组时只有一个字母,则补充字母z
3.若明文字母在矩阵中同行,则循环取其右边下一个字母为密文(矩阵最右边的下一个是最左边的第一个)(eg: ar被加密为RM)
4.若明文字母在矩阵中同列,则循环取其下边下一个字母为密文(矩阵最下边的下一个是最上边的第一个)(eg: mu被加密为CM)
5.若明文字母在矩阵中不同行不同列,则取其同行且与同组另一字母同列的字母为密文(eg: hs被加密为BP,ea被加密为IM或JM)
  • 举例:
明文为we are discovered save yourself,分组成为we ar ed is co ve re ds av ey ou rs el fz;
用上述矩阵加密后的密文为:UG RM KC SX HM UF MK BT OX GC MV AT LU KV
下面为代码 解密之后还没解决一些问题
import string #j用i代替 table="abcdefghiklmnopqrstuvwxyz" def get_key(key): key=key.lower() k=[] c=[] j=0 k1=[] for i in key: if(i not in k1): if(i=='j'): i='i' c.append(i) k1.append(i) j+=1 if(j==5): j=0 k.append(c) c=[] for i in table: if(i not in k1): c.append(i) k1.append(i) j += 1 if (j == 5): j = 0 k.append(c) c = [] return k def get_position(m,key): for i in range(5): for j in range(5): if(m==key[i][j]): return i,j def encrypt(m,key): m1='' l=len(m) i=0 #两两分组相同字母不能在同一组 while(i<len(m)-1): if(m[i]==m[i+1]): m1=m1+m[i]+'z' i=i+1 l+=1 else: m1=m1+m[i]+m[i+1] i+=2 #两两分组如果长度为奇数则末尾加z if(l%2==1): m1=m1+m[len(m)-1]+'z' print(m1) c='' for i in range(0,l,2): i1,j1=get_position(m1[i],key) i2,j2=get_position(m1[i+1],key) #在同一行 if(i1==i2): c=c+key[i1][(j1+1)%5]+key[i1][(j2+1)%5] #在同一列 elif(j1==j2): c=c+key[(i1+1)%5][j1]+key[(i2+1)%5][j2] else: c=c+key[i1][j2]+key[i2][j1] return c def decrypt(c,key): m = '' for i in range(0, len(c), 2): i1, j1 = get_position(c[i], key) i2, j2 = get_position(c[i + 1], key) # 在同一行 if (i1 == i2): m = m + key[i1][(j1 - 1) % 5] + key[i1][(j2 - 1) % 5] # 在同一列 elif (j1 == j2): m = m + key[(i1 - 1) % 5][j1] + key[(i2 - 1) % 5][j2] else: m = m + key[i1][j2] + key[i2][j1] #如果最后一位是z则去掉 if(m[len(m)-1]=='z'): m=m[:-1] return m key=input("输入密钥: ") key=get_key(key) message=input("输入明文: ") message=message.replace('j','i').replace(' ','') cipher=encrypt(message,key) print(cipher) message=decrypt(cipher,key) print(message)
ECCCISCN

Putao0v0
Putao0v0
ctfer | 张星特
公告
type
Notice
status
Published
date
Apr 4, 2023
slug
#
summary
类型为Notice的文章将被显示为公告,仅 hexo和next支持;仅限一个公告
tags
category
icon
password
hi~一个新站