题目一
密钥矩阵的构造
新建5x5的表格,依次填入密钥单词,字母不重复,然后字母a-z一次不重复填入,注意字母i和字母j占据同一个位置,一般来说加密的时候明文中的j字母都可以替换成字母i。
密文两两分组
密文:
KXJEY UREBE ZWEHE WRYTU HEYFS
KREHE GOYFI WTTTU OLKSY CAJPO
BOTEI ZONTX BYBWT GONEY CUZWR
GDSON SXBOU YWRHE BAAHY USEDQ
值得注意的是,这里每一个分组的两字母是不重复的(加密过程会注意这一点,不过本题目只是解密)。
取小写、替换j为i、两两分组的脚本:
ciper =
"KXJEYUREBEZWEHEWRYTUHEYFSKREHEGOYFIWTTTUOLKSYCAJPOBOTEIZONTXBYBWTGONEYCUZWRGDSONSXBOUYWRHEBAAHYUSEDQ"
ciper = ciper.lower()
ciper = ciper.replace('j','i')
cl = [ciper[i:i+2] for i in range(len(ciper)) if i%2 == 0]
结果:
解题过程
使用脚本书写针对‘royal new zealand navy’密钥系统的playfair解密算法:
# 寻找二维列表中指定元素的索引坐标,不存在返回None
# 可扩展到numpy.array或numpy.matrix等二位数组、矩阵类型
def find_element(matrix, value):
for row in range(len(matrix)):
if value in matrix[row]:
return (row, matrix[row].index(value))
return None
# 解密密钥矩阵
DecodeKeyMatrix = [
['r', 'o', 'y', 'a', 'l'],
['n', 'e', 'w', 'z', 'd'],
['v', 'b', 'c', 'f', 'g'],
['h', 'i', 'k', 'm', 'p'], # i/j代表同一个元素
['q', 's', 't', 'u', 'x']
]
def decode(twoletter_ciper):
global DecodeKeyMatrix
(_1r, _1c) = find_element(DecodeKeyMatrix, twoletter_ciper[0])
(_2r, _2c) = find_element(DecodeKeyMatrix, twoletter_ciper[1])
if _1r == _2r:
return DecodeKeyMatrix[_1r][_1c - 1] + DecodeKeyMatrix[_2r][_2c - 1]
elif _1c == _2c:
return DecodeKeyMatrix[_1r - 1][_1c] + DecodeKeyMatrix[_2r - 1][_2c]
else:
return DecodeKeyMatrix[_1r][_2c] + DecodeKeyMatrix[_2r][_1c]
执行主函数:
if __name__ == '__main__':
plaintext = ""
ciper = "KXJEYUREBEZWEHEWRYTUHEYFSKREHEGOYFIWTTTUOLKSYCAJPOBOTEIZONTXBYBWTGONEYCUZWRGDSONSXBOUYWRHEBAAHYUSEDQ"
ciper = ciper.lower()
ciper = ciper.replace('j','i')
cl = [ciper[i:i+2] for i in range(len(ciper)) if i%2 == 0]
for twoletter in cl:
plaintext += decode(twoletter)
print(plaintext)
执行结果:
去除占位符X,得到明文:pt boat one owe nine lost in action in blackess strait two miles sw meresu coce crew of twelve request any information
题目二
本题是playfair密码算法的加密过程
使用密钥矩阵:
#加密密钥矩阵
#会比解密矩阵多最后一行(对应第一行)、最后一列(对应第一列)的冗余
EncodeKeyMatrix = [
['m','f','h','i','k','m'],
['u','n','o','p','q','u'],
['z','v','w','x','y','z'],
['e','l','a','r','g','e'],
['d','s','t','b','c','d'],
['m','f','h','i','k',None]
]
加密算法:
def encode(twoletter_text):
global EncodeKeyMatrix2
(_1r, _1c) = find_element(EncodeKeyMatrix2, twoletter_text[0])
(_2r, _2c) = find_element(EncodeKeyMatrix2, twoletter_text[1])
if _1r == _2r:
return EncodeKeyMatrix2[_1r][_1c + 1] + EncodeKeyMatrix2[_2r][_2c + 1]
elif _1c == _2c:
return EncodeKeyMatrix2[_1r + 1][_1c] + EncodeKeyMatrix2[_2r + 1][_2c]
else:
return EncodeKeyMatrix2[_1r][_2c] + EncodeKeyMatrix2[_2r][_1c]
还有些一个初始化函数init(),来处理明文:取小写、去除特殊标点符号、末尾补齐(使明文长度为偶数)、两两分组;最后一个任务是关键点,分组字母不能相同,若是则要在中间差值字母'x'或'q':
def detect(s):
if len(s) == 2 and s[0] == s[1]:
temp = 'x' if s[0] != 'x' else 'q'
return s[0] + temp + s[0]
else:
return s
def init(info):
info = info.lower()
info = re.sub(" |.|,", "", info)
while True:
flag = 0
info_li = [info[i:i+2] for i in range(len(info)) if i%2 == 0]
_li = map(detect, info_li)
for word in _li:
if len(set(word)) == 3:
flag = 1
break
info = ''.join(_li)
if not flag:
break
info += 'x' if len(info)%2==1 else ''
if info[-2] == 'x':
info[-1] == 'q'
return info
可以看一下效果:
现在给see单词中多添加一个字母s变成ssee,查看效果:
主函数代码:
ciper = ""
message = "Must see you over Cadogan West.Coming at once."
message = init(message)
mess_li = [message[i:i+2] for i in range(len(message)) if i%2 == 0]
for twoletter in mess_li:
ciper += encode(twoletter)
print(ciper)
加密结果: