5.7 维吉尼亚密码

任务描述

本关任务:编写程序,通过维吉尼亚密码将密文解密成文本。

相关知识

维吉尼亚密码——解密

凯撒密码的加密强度是很低的,只需简单地统计字频就可以破译。人们在单一凯撒密码的基础上扩展出多表密码,称为维吉尼亚密码。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

维吉尼亚密码引入了密钥的概念,即根据密钥来决定用哪一行的密码表来进行替换,以此来对抗字频统计。

假如以上面第一行代表明文字母,左面第一列代表密钥字母,对如下明文加密:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

TO BE OR NOT TO BE THAT IS THE QUESTION‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

当选定RELATIONS作为密钥时,加密过程是:明文一个字母为 T ,第一个密钥字母为 R ,因此可以找到在 R 行中代替 T 的为 K ,依此类推,得出对应关系如下:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

密钥: RE LA TI ONS RE LA TION SR ELA TIONSREL‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

明文: TO BE OR NOT TO BE THAT IS THE QUESTION‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

密文: KS ME HZ BBL KS ME MPOG AJ XSE JCSFLZSY‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

小写字母采用相同的加密表格和加密方法(将上述方法里的大写字母换为小写字母即可)。

遇到数字时,可将其密钥字母在密码表中的偏移量对10取模的结果作为在数字表格中的偏移量,例如:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

1的密钥 R 在表格中的偏移量为 17A 在字母表里的偏移量为 0),偏移量对 10 取模结果为 7 ,加密时,查表格中 1 对应的列 1 2 3 4 5 6 7 8 9 0 中序号为 7 的数字,得到加密结果应为 89 的密钥“E”的偏移量是 4 ,在 9 对应的行中序号为 4 的数字是 3 。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

第1关:维吉尼亚密码——解密

import string

def vigenere_decrypt(text, key):
    """接收密文字符串和密钥字符串为参数,返回解密后的字符串.
    解密时字母和数字以外的其他字符原样输出。"""
    lower_tab = string.ascii_lowercase    # 小写字母
    upper_tab = string.ascii_uppercase    # 大写字母
    digit_tab = string.digits

    #####################Begin#####################################
    # 此处去掉注释符号“#”并补充你的代码
    times = 0
    plaintext = ''
    for letter in text:
        index = times % len(key)
        offset = upper_tab.find(key[index])
        if letter in upper_tab:
            upper_offset = upper_tab[offset:] + upper_tab[:offset]
            plaintext = plaintext + upper_tab[upper_offset.find(letter)]
            times = times + 1
        elif letter in lower_tab:
            lower_offset = lower_tab[offset:] + lower_tab[:offset]
            plaintext = plaintext + lower_tab[lower_offset.find(letter)]
            times = times + 1
        elif letter in digit_tab:
            offset = offset % 10
            digit_offset =digit_tab[offset:] + digit_tab[:offset]
            plaintext = plaintext + digit_tab[digit_offset.find(letter)]
            times = times + 1
        else:
            plaintext = plaintext + letter

    return plaintext

    #####################End#####################################

if __name__ == '__main__':
    secret_key = input()
    cipher_text = input()
    plain_text = vigenere_decrypt(cipher_text, secret_key)
    print(f'解密后得到的明文是{plain_text}')

第2关:维吉尼亚密码——加密

按理来说按照第解密反推就行,但是整了好几次还是有点问题,问题不大,明天继续肝

猜你喜欢

转载自blog.csdn.net/m0_70456205/article/details/130049948