了解python

时间:2015-11-07 16:02:03

标签: python encryption

作为作业的一部分,我已经获得了一些用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变量的串联,但是我承认我不明白这样做的目的。

我意识到这是一个很长的问题,但我认为最好把困扰我的部分放到上下文中。

1 个答案:

答案 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",看起来我们应该执行另一个解密步骤。在 但是,我确信教授可以选择明文 不是以这样的数字开头(除非他们真的很邪恶)。