维吉尼亚密码加密和解密Python

目录

相关知识

维吉尼亚密码——解密

编程要求

加密代码实现

相关知识

维吉尼亚密码——加密

编程要求

解密代码实现

测试说明


相关知识

维吉尼亚密码——解密

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

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

图片

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

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

密钥: RELA

明文: 1945

密文: 8355

解密方法与上述操作正好相反,先查出当前字符在密码表中偏移后的位置,再到初始字符集中查找对应的字符。

你的好朋友小明在星期三的早晨给你发了一封电子邮件,你看到的内容是 Kr Dhkmvt 0, 3378, xzh Ulexhq Wldtco hubthhd rdi fbhw qakah "ovxloe zkc" rs xzh arkqlp fgpbgjk rs Lauoqdmpn, Nssal.

然后在你在QQ 收到小明发给你的这样一条消息:维吉尼亚问你今天是星期几? 聪明的你猜出来邮件内容是用维吉尼亚加密方法加密过的,密钥是星期三(收到消息的日期)的英文单词(Wednesday),写个程序解密小明的邮件并输出明文吧! 提示:小明发来的消息是: On August 6, 1945, the United States dropped the code named "little boy" of the atomic bombing of Hiroshima, Japan.

编程要求

根据提示,在右侧编辑器补充代码,通过维吉尼亚密码将密文解密成文本。

注意:密钥字符串中可能包含有大小写字母,因此计算偏移量时需要注意大小写统一计算。

加密代码实现

import string

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

    # 补充你的代码
    plain_text = ''
    key_index = 0
    for char in text:
        if char.isupper():
            offset = ord(key[key_index % len(key)].upper()) - ord('A')
            plain_text += upper_tab[(upper_tab.index(char) - offset) % 26]
            key_index += 1
        elif char.islower():
            offset = ord(key[key_index % len(key)].lower()) - ord('a')
            plain_text += lower_tab[(lower_tab.index(char) - offset) % 26]
            key_index += 1
        elif char.isdigit():
            offset = ord(key[key_index % len(key)].upper()) - ord('A')
            plain_text += digit_tab[(digit_tab.index(char) - offset) % 10]
            key_index += 1
        else:
            plain_text += char
 
    return plain_text
    

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

相关知识

维吉尼亚密码——加密

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

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

图片

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

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

密钥: RELA

明文: 1945

密文: 8355

编程要求

根据提示,在右侧编辑器补充代码,通过维吉尼亚密码将文本加密成密文。

解密代码实现

import string

def vigenere_encryption(text, key):
    """接收明文字符串和密钥字符串为参数,返回加密后的字符串.
    加密时字母和数字以外的其他字符原样输出。
    数字加密时,根据对应的密钥字符在字母表中的偏移量对10取模得到数字的偏移量。
    例如当前数字为1,对应的密钥字母是R,R的偏移量是17,对10取模为7,1 2 3 4 5 6 7 8 9 0 中序号为7的数字是8,加密结果即为8"""
    lower_tab = string.ascii_lowercase  # 小写字母
    upper_tab = string.ascii_uppercase  # 大写字母
    digit_tab = string.digits
    # 补充你的代码
    cipher_text = ''
    key_index = 0
    for char in text:
        if char.isupper():
            offset = ord(key[key_index % len(key)].upper()) - ord('A')
            cipher_text += upper_tab[(upper_tab.index(char) + offset) % 26]
            key_index += 1
        elif char.islower():
            offset = ord(key[key_index % len(key)].lower()) - ord('a')
            cipher_text += lower_tab[(lower_tab.index(char) + offset) % 26]
            key_index += 1
        elif char.isdigit():
            offset = ord(key[key_index % len(key)].upper()) - ord('A')
            cipher_text += digit_tab[(digit_tab.index(char) + offset) % 10]
            key_index += 1
        else:
            cipher_text += char
 
    return cipher_text


if __name__ == '__main__':
    secret_key = input()
    plain_text = input()
    plain_to_cipher_text = vigenere_encryption(plain_text, secret_key)
    print(f'加密后得到的密文是{plain_to_cipher_text}')

测试说明

平台会对你编写的代码进行测试:

测试输入1:

 
  1. winter
  2. The harsh winter will be gone and spring is around the corner.

预期输出1:

 
  1. 加密后得到的密文是Ppr aeiop jbrkaz jbpc xm thrv wvq ltievt bw rnwhgh kdm phveaz.

测试输入2:

 
  1. EARTH
  2. I'll see you on Mars in 2030

预期输出2:

 
  1. 加密后得到的密文是M'lc lli yfn vr Mrkz mn 9904
  • 24
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值