使用python破解一些密码问题的例子

发表于 Python, 程序语言 2017-02-23 阅读数: 106

这是pythonchallenge上的第二关,比较简单。

题目给了下面这个HINT:

Python 破解密码

以及一串看起来很乱的字母:

g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyr

q ufyr amknsrcpq ypcdmp. bmgle gr gl zw fyl

b gq glcddgagclr ylb rfyr'q ufw rfgq rcvr g

q qm jmle. sqgle qrpgle.kyicrpylq() gq pcam

kkclbcb. lmu ynnjw ml rfc spj.

根据图片里的规律,我们得知其是字母向右移动两位。那么原文也就是ASCII码减二的加密方式。这就是凯撒密码。

你如果有耐心的话,可以一个一个的往右移两个字母,从而得出答案。但我们应该更追求更高效的方法。

Python中有这样的两个函数:

ord():返回一个字符的ASCII码

chr():获取一个ASCII码,将它转换为字符

我们或许可以利用这两个函数解密。

核心代码:

for each in text:

    if ord(each) >= ord('a') and ord(each) <= ord('z'):

        answer = answer + chr(ord(each) + 2)

代码意思是这样的:检测字符串内的每一个字符,若它是小写字母(介于a和z之间)那么就将它的ASCII码加二并转化为字符。

因为文中只有小写字母,所以我们只需要考虑小学的,若有大写字母,你只需要添加多两个and并列进 if 即可。

我们查看转换的结果:

Python 破解密码

并不是很理想,有些字符,如本应该是a的变成了{ , b变成了I. 这是为什么?

我们观察原文发现 'a' 的原文是 'y' , 'b' 的原文是 'z'. 这样我们就明白了,ASCII码后面的那几个小写字符+2后识别成了其他字符。实际上当他们+2超过26的时候,就应该从1的a开始。这个问题怎么解决呢?

你可以单独在if内设置条件,比如

if(ord(each) == 25)

    answer = answer + 'a'

但是这样不利于普遍化,到时候如果它不是向右移动两位,而是十位的时候该怎么办?

解决办法是,先将该字符按照我们先前的办法转换,然后取模26,这样的话低于等于26的不会变,本来是27的会变成1,这样就能成功表示转换后的a和b. 最后再加上a的ASCII(为了得到其他字符的ASCII码,便于转换成字符),最后转换成字符。

完整代码如下:

text = """

g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyr

q ufyr amknsrcpq ypcdmp. bmgle gr gl zw fyl

b gq glcddgagclr ylb rfyr'q ufw rfgq rcvr g

q qm jmle. sqgle qrpgle.kyicrpylq() gq pcam

kkclbcb. lmu ynnjw ml rfc spj.

"""

answer = ""

for each in text:

    if ord(each) >= ord('a') and ord(each) <= ord('z'):

        answer = answer + chr((ord(each) + 2 - ord('a')) % 26 + ord('a'))

    else:

        answer = answer + each

print(answer)

欢迎关注微信公众号:幻象客www.huanxiangke.com

幻象客 二维码

Add comment