Checkio Rotating Grille Cipher(旋转栅格密码)

在此任务中,您将获得一条消息和一把钥匙(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'

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值