字符串编解码方法

逆向工程 加密 Python 编码
2021-07-08 13:19:32

所以我在python中遇到了以下字符串编码方法。

def encode(the_string):
    encoded_string = ''
    rotations = ord(the_string[-1]) + 5

    for i in range(0, len(the_string)):
        value = ord(the_string[i])

        for j in range(0, rotations):
            value -= 1
            if value < 65:
                value = 25 + value

        encoded_string += chr(value)
        rotations += ord(the_string[i])-2
    return encoded_string

它看起来像一个凯撒密码,其中字母的 ASCII 值决定了字母表的移位次数,但“Z”留在最后。初始旋转数是字符串最后一个字母的 ASCII 值加 5。

def encode(the_string):
   ALPHABET='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

   encoded_string = ''
   rotations = (ord(the_string[-1]) + 5) % 25

   for i in range(0, len(the_string)):
       alphabet_rotate = ALPHABET
       print('Rots:',rotations)
       for j in range(0, rotations):
           alphabet_rotate = alphabet_rotate[1:-1] + alphabet_rotate[0] + alphabet_rotate[-1]

       encoded_string += ALPHABET[alphabet_rotate.index(the_string[i])]
       rotations += (ord(the_string[i]) - 2) 
       rotations %= 25

   return encoded_string

我正在尝试编写一种解码方法,但是我正在努力为旋转找到正确的偏移量。我正在扭转转变的方向。解码字母的查找也反向工作。这是正确的方法吗?任何帮助将不胜感激。

def decode(the_string):
    ALPHABET='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

    decoded_string = ''
    rotations = (ord(the_string[-1]) + 3) % 25 # <== 1. PROBLEM HERE

    for i in range(0, len(the_string)):
        alphabet_rotate = ALPHABET

        for j in range(0, rotations):
            alphabet_rotate = alphabet_rotate[-2] + alphabet_rotate[0:-2] + alphabet_rotate[-1]

        decoded_string += alphabet_rotate[ALPHABET.index(the_string[i])]

        rotations += (ord(the_string[i]) +20 ) # <== 2. PROBLEM HERE
        rotations %= 25

    return decoded_string   
1个回答

先说几点意见:

  • 初始旋转基于我们不知道的纯文本字符,所有进一步的旋转也是如此。因此,我认为我们不能直接解码给定的字符串。

  • 可以对 AZ 以外字符的明文进行编码,但我不确定我们是否可以正确解码它们。对于我的分析,我仅假设 AZ 输入。

  • 旋转似乎有些奇怪,因为它实际上idx % 25代替了 26。如果输入字符低于 65 (='A'),它将被旋转到 'Y',而不是 'Z'。

也就是说,以下解码给定的编码字符串和给定的初始旋转(未知):

def decode(string,initial):
    alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    rot = initial

    decoded = ""

    for i in range(len(string)):
        c = string[i]
        plain = alph[(alph.index(c)+rot) % (len(alph)-1)]
        decoded += plain

        rot += ord(plain)-2

如果我们在 encode 函数中添加一行来输出初始旋转,我们可以测试一下:

print(decode(encode("HELLO"),84))

打印HELLO正确给定的84初始旋转通过修改打印encode功能。

现在我们有了一条线索来验证我们是否得到了正确的解码。第一个旋转和最后一个明文字符的关系:

first rot = ord(last plaintext char) + 5

所以我们可以测试所有初始旋转并验证上述内容。

但是,等式是在模 25 下的。例如,可以使用初始旋转 84 正确解码“HELLO”行 - 但也可以使用 9(通过执行 84 % 25 获得)。

如果我们编写一个函数来找到这样的正确解码:

def find_decoding(string):
    for i in range(26):
        decoded = decode(string,i)
        if ((ord(decoded[-1])+5) % 25) == i:
            print("Key %d valid: %s" % (i,decode(string,i)))

然后我们可以找到上述关系成立的初始旋转。有趣的是,'HELLO' 似乎是一个罕见的输入,在 0-25 范围内有多个可能的键:

Key 4 valid: CTQVJ
Key 9 valid: HELLO
Key 14 valid: MOGBT
Key 19 valid: RYBQY
Key 24 valid: WJVGE

但是我随机尝试的任何其他字符串只有一个有效的初始旋转。