在此任务中,您将获得一条消息和一把钥匙(4x4方形格栅);消息的长度可以被 16 整除。您需要使用旋转格栅密码加密消息。 但是,有一个问题:某些密钥有缺陷。 “正确”键的制作方式是,当放置在网格上并旋转时,每个单元格都只显示一次。 因此,对于有缺陷的键,要么某些单元格显示不止一次,要么在所有四个方向上应用键后,工作表上仍有未填充的空间。 请参阅下面的坏键示例:
grille_encrypt('cardangrilletest', ['.X..', '.X..', '...X', 'X...']) == 'actilangeslrdret'
grille_encrypt('quickbrownfoxjumpsoverthelazydog',
['X...', '...X', '..X.', '.X..']) == 'qxwkbnjufriumcoopyeerldsatoogvhz'
grille_encrypt('quickbrownfoxjumpsoverthelazydog',
['.XX.', '.XX.', '..X.', 'X...']) == None
grille_encrypt('cardangrilletest', ['...X', '....', '....', '....']) == None
如果密钥正确,则返回加密消息;如果密钥有缺陷 - 返回 None。
输入:明文:str,格栅:str 列表(孔的位置用“Х”标记) )
输出:密文:str 或 None
# 判断栅格是否是有问题的
def replacegrill(new_grill, rotate_grill):
"""将旋转后的栅格中的X与原栅格对应·位置的值进行替换"""
return [
[
cell if cell == 'X' else (
replacement_cell if replacement_cell == 'X' else cell)
for cell, replacement_cell in zip(row, replacement_row)
] for row, replacement_row in zip(new_grill, rotate_grill)
]
def check_grill(grill):
"""检查给定的栅格是否能够在多次旋转后填满4 × 4 栅格,如果能满足就将每个栅格的坐标导出"""
if sum(char == 'X' for char in "".join(grill)) == 4:
grill = [[grill[i][j] for j in range(4)] for i in range(4)]
true_grill = [['X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X'],
['X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X']]
new_grill = grill.copy() # 创建一个new_grill变量用以保存叠加后的栅格,使grill保持每次都只有四个窗口
grill_pos = []
for _ in range(4):
grill_pos.append([(i, j) for i, row in enumerate(grill)
for j, char in enumerate(row) if char == 'X']) # 获取grill的X坐标
# print(grill)
rotate_grill = list(zip(*grill[::-1])) # grill旋转九十度
# print(rotate_grill)
new_grill = replacegrill(new_grill, rotate_grill) # 旋转叠加“X”替换
# print(new_grill)
# print("__________________________")
grill = rotate_grill # grill继承当前旋转后的值,下一循环继续旋转
return None if new_grill != true_grill else grill_pos
return None
def encrypt(password, grill):
if check_grill(grill):
grill_pos = check_grill(grill)
pass_slices = [password[i:i+4] for i in range(0, 16, 4)]
cipher_grille = []
for position_group, slice in zip(grill_pos, pass_slices):
cipher_grille.append(list(zip(position_group, slice)))
cipher_grille = [item for sublist in cipher_grille for item in sublist]
# print(cipher_grille)
sorted_cipher_grill = sorted(cipher_grille, key=lambda x: x[0])
# print(sorted_cipher_grill)
# 取出列表中每项所含的字符串
return "".join(block[1] for block in sorted_cipher_grill)
"""
# 填充字符到矩阵中
matrix = [[' ' for _ in range(4)] for _ in range(4)] #创造空矩阵
for coord, char in sorted_cipher_grill:
x, y = coord
matrix[x][y] = char
return matrix
"""
return None
# 当要加密多段文字时
def grille_encrypt(password, grill):
try:
if len(password) > 16:
cipher = ""
for password_block in [password[i:i+16] for i in range(0, len(password), 16)]:
cipher += "".join(encrypt(password_block, grill))
return cipher if encrypt(password_block, grill) else None
else:
return encrypt(password, grill)
except: # 错误回执
return None
grille_encrypt('cardangrilletest', [
'.X..', '.X..', '...X', 'X...']) == 'actilangeslrdret'