PalyFair 密码
Playfair密码基于一个5*5字母矩阵,该矩阵使用一个关键词(密钥)来构造,其构造方法是:从左至右、从上至下依次填入关键词的字母(去除重复的字母),然后再以字母表顺序依次填入其他字母。字母I和J被算为一个字母(即J被当做I处理)。
对每一对明文字母M1、M2的加密方法如下:
- 若M1、M2在同一行时,则对应的密文C1和C2分别是紧靠M1、M2右端的字母。其中第一列被看做是最后一列的右方(解密时反向)。
- 若M1、M2在同一列时,则对应的密文C1和C2分别是紧靠M1、M2下方的字母。其中第一行看做是最后一行的下方(解密时反向)。
- 若M1、M2不在同一行,也不在同一列时,则C1和C2是由M1和M2确定的矩形的其他两角的字母,并且C1和M1、C2和M2同行(解密时处理方法相同)。
- 若M1=M2,则插入一个字母(如约定为Q)于重复字母之间,并用前述方法处理。
- 若明文字母为奇数时,则在明文的末端添加某个事先约定的字母作为填充
直接上代码
random_word = None
key_array = []
def encriypt(plain_text,key_words):
global random_word,key_array
plain_array = []
for i in plain_text.upper():
if i == ' ':
continue
plain_array.append(i)
key_array = []
for i in key_words.upper():
if i not in key_array:
if i== ' ':
continue
key_array.append(i)
for i in range(26):
letter = chr(65+i)
if letter not in key_array and letter != "J":
if random_word == None and letter not in plain_array:
random_word = letter
key_array.append(letter)
for i in range(0,len(plain_array),2):
if plain_array[i] == plain_array[i+1]:
plain_array.insert(i+1,random_word)
if len(plain_array)%2 == 1:
plain_array.append(random_word)
ciphertext = []
for i in range(0,len(plain_array),2):
i_index = key_array.index(plain_array[i])
i1_index = key_array.index(plain_array[i+1])
if i_index%5 == i1_index%5:
ciphertext.append(key_array[(i_index+5)%25])
ciphertext.append(key_array[(i1_index + 5) % 25])
elif int(i_index/5) == int(i1_index/5):
ciphertext.append(key_array[int(i_index/5)*5+(i_index + 1) % 5])
ciphertext.append(key_array[int(i1_index/5)*5+(i1_index + 1) % 5])
else:
if i_index%5 > i1_index%5:
num = i_index%5 - i1_index%5
ciphertext.append(key_array[i_index-num])
ciphertext.append(key_array[i1_index+num])
if i_index%5 < i1_index%5:
num = i1_index%5 - i_index%5
ciphertext.append(key_array[i_index+num])
ciphertext.append(key_array[i1_index-num])
content = ''
for i in ciphertext:
content = content + i
return content
def deciphering(ciphertext):
global key_array,random_word
text = []
for i in range(0,len(ciphertext),2):
i_index = key_array.index(ciphertext[i])
i1_index = key_array.index(ciphertext[i + 1])
if i_index % 5 == i1_index % 5:
text.append(key_array[(i_index +20) % 25])
text.append(key_array[(i1_index + 20) % 25])
elif int(i_index / 5) == int(i1_index / 5):
text.append(key_array[int(i_index/5)*5+(i_index + 4) % 5])
text.append(key_array[int(i1_index/5)*5+(i1_index + 4) % 5])
else:
if i_index%5 > i1_index%5:
num = i_index%5 - i1_index%5
text.append(key_array[i_index-num])
text.append(key_array[i1_index+num])
if i_index%5 < i1_index%5:
num = i1_index%5 - i_index%5
text.append(key_array[i_index+num])
text.append(key_array[i1_index-num])
content = ''
for i in text:
if i == random_word:
continue
content = content + i
return content
# monarchy
if __name__ == '__main__':
plain_text = str(input("明文:"))
key_words = str(input("密钥词:"))
ciphertext = encriypt(plain_text,key_words)
print("密文:",ciphertext)
print("约定字母:",random_word.lower())
text = deciphering(ciphertext)
print("明文:",text.lower())