Python基础练习(五):破译密码

题目描述

题目内容:

A国情报局抓获敌国间谍一名,从间谍身上搜出了若干密电,在严刑逼供之下,间谍说出了密电加密方法:将明文电报(仅由大写字母构成)中的所有字母均替换为字母表中向后看的第n个字母,如果超过Z,则从A继续数,这样就得到了密文,比如ATTACK,向后看第2个字母,就加密为CVVCFM。

可还没等到间谍说出加密用的密钥(数字n),就被卧底开枪打死,间谍临死前在地板上画了BYE三个字母。

情报局长看着一条条密电发了愁,但机智的你已经发现,原来间谍在告诉我们,所有密电的明文都以BYE结尾!

请编写程序破译这些密电吧!

输入格式:

共一行字符串,全部由大写字母构成的密文。

输出格式:

共一行字符串,破译后的明文。

输入样例1:

JNTQZCZF

输出样例1:

IMSPYBYE

时间限制:500ms内存限制:32000kb

解题思路

原始思路

  1. 所有密电明文均以BYE结尾,因此我们可以利用该条件获知密钥n。(通过密文的最后三位字母中的任意一个均可获取,n即为对应位置的字母编码值的差值)
  2. 如果明文超过“Z”,则从“A”继续数,这里我们可以借助其与26的差值得到。(英文字母总个数为26)
  3. 将密文和明文分为两部分,最后三位和其他部分,分别计算即可
a = input().upper()
b = ""
n = ord('E')-ord(a[-1])
for i in a[:-3]:
    if ord(i)+n>ord("Z"):
        b += chr(ord(i)+n-26)
    else:
        b += chr(ord(i)+n)
b += "BYE"
print(b)

思路缺陷

在第一步中考虑不周,忽视了n的取值范围。举例说明,若a[-1]=“Z”,则n=-21,那么当ord(i)=65,即i="a"时,chr的值就已不是任何一个大写字母
在这里插入图片描述

思路改进

将n的取值分情况讨论,计算出n的精确值

换种想法

对于具有周期性的数列,取余数不失为一种好方法

  1. 生成一个包含26个字母并且顺序排列的列表,或可简称为字母表(`・ω・´)
  2. 按照题目要求,先求出密钥n
  3. 利用密钥n求解密文移动后的位置,利用余数求解明文( 划重点 :由于此前已经生成新的字母表,范围在在[0,25]内,所以此时利用生成后的位置数对26(字母个数)取余极为方便)

解题代码

思路一

a = input().upper()
b = ""
if a[-1]<='E':
    n = ord('E')-ord(a[-1])
else:
    n = 26+(ord('E')-ord(a[-1]))
for i in a[:-3]:
    if ord(i)+n>ord("Z"):
        b += chr(ord(i)+n-26)
    else:
        b += chr(ord(i)+n)
b += "BYE"
print(b)

思路二

a = input().upper()
l = [chr(i) for i in range(ord("A"),ord("Z")+1)]
n = l.index('E')-l.index(s[-1])
b = ""
for i in a[:-3]:
        b += l[(l.index(i) + n)%26]
b += "BYE"
print(b)
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值