作为作业的一部分,我已经获得了一些用python编写的用于加密消息的代码,我必须尝试理解代码并解密密文。我之前从未使用过python,而且有点超出我的深度。
我理解其中的大部分内容以及代码试图完成的内容的总体要点,但是有几行接近尾声绊倒了我。这是整个事情(&&&表示应该被“损坏”的代码部分,同时测试我设置秘密的代码“test”并计入3):
import string
import random
from base64 import b64encode, b64decode
secret = '&&&&&&&&&&&&&&' # We don't know the original message or length
secret_encoding = ['step1', 'step2', 'step3']
def step1(s):
_step1 = string.maketrans("zyxwvutsrqponZYXWVUTSRQPONmlkjihgfedcbaMLKJIHGFEDCBA","mlkjihgfedcbaMLKJIHGFEDCBAzyxwvutsrqponZYXWVUTSRQPON")
return string.translate(s, _step1)
def step2(s): return b64encode(s)
def step3(plaintext, shift=4):
loweralpha = string.ascii_lowercase
shifted_string = loweralpha[shift:] + loweralpha[:shift]
converted = string.maketrans(loweralpha, shifted_string)
return plaintext.translate(converted)
def make_secret(plain, count):
a = '2{}'.format(b64encode(plain))
for count in xrange(count):
r = random.choice(secret_encoding)
si = secret_encoding.index(r) + 1
_a = globals()[r](a)
a = '{}{}'.format(si, _a)
return a
if __name__ == '__main__':
print make_secret(secret, count=&&&)
基本上,我假设代码是从三个加密方法step1,step2和step3中随机选择,然后将它们应用于一个或多个明文,由“count”的值控制。
“make_secret”方法是困扰我的部分,因为我很难弄清楚它是如何将所有东西联系在一起的,以及它的总体目的是什么。我将逐行完成并在每个部分给出我的理由,如果我弄错了,有人可以纠正我。
a = '2{}'.format(b64encode(plain))
这将采用“plain”变量对应的base64编码,并在其开头附加2,导致类似“2VGhpcyBpcyBhIHNlY3JldA ==”的内容,使用“this is a secret”作为测试。我不确定2是什么。
r = random.choice(secret_encoding)
si = secret_encoding.index(r) + 1
r是来自secret_encoding数组的随机选择,而si对应于r之后的下一个数组元素。
_a = globals()[r](a)
这是让我难过的部分之一。从研究global()看来,这里的意图似乎是将“r”变成一个由“a”中的字符组成的全局字典,即在代码后面的某个地方,a的字符将被用作有限的字符集供选择。这是正确的还是我离开基地?
我已经尝试打印_a,这给了我看起来在代码的最终输出中找到的字母和数字。
a = '{}{}'.format(si, _a)
好像这是创建一个字符串,它是si和_a变量的串联,但是我承认我不明白这样做的目的。
我意识到这是一个很长的问题,但我认为最好把困扰我的部分放到上下文中。
答案 0 :(得分:2)
我将不会评论代码的可读性。我敢说 无论如何,出于混淆的目的,这都是故意的。您的 教授是一个邪恶的混蛋,我想接受他或她的课程:)
r = random.choice(secret_encoding)
...
_a = globals()[r](a)
你离开了基地。这本质上是一种丑陋且难以阅读的方式
随机选择三个函数中的一个并在a
上运行它。该
function globals()
返回将名称映射到标识符的dict
;它
包括三个功能和其他东西。 globals()[r]
查找
基于名称r
的三个函数之一。之后放(a)
以a
为参数运行函数。
a = '{}{}'.format(si, _a)
这里的想法是在每个中间结果的前面加上数字 加密它的函数,所以你知道你需要哪个函数 反向解密该步骤。他们都在开始时积累,并且 每一步都加密并重新加密,除了最后一步。
a = '2{}'.format(b64encode(plain))
基本上,这是首先应用step2
。每次加密用
step2
预先加2
。
因此,该程序将count
加密应用于明文,每个加密
使用随机选择的转换步骤,选择出现在
密文之前的明文。你的任务是阅读每个前置的
编号并将逆转换应用于消息的其余部分。
当第一个字符不在"123"
中时停止。
我看到的一个问题是,如果明文以数字开头
"123"
,看起来我们应该执行另一个解密步骤。在
但是,我确信教授可以选择明文
不是以这样的数字开头(除非他们真的很邪恶)。