Python 中的异或密码:两种方法,两种结果



最近,我一直在探索Python中的XOR密码。 我有两种"工作"方法:

def XORcipher(plaintext, key):
    output = ""
    for character in plaintext:
        for letter in key:
            character = chr(ord(character) ^ ord(letter))
        output += character
    return output

def XORcipher2(plaintext, key):
    from itertools import izip, cycle
    return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(plaintext, cycle(key)))

两者都能够加密给定的字符串并解密回来。 我似乎无法理解的是为什么它们会给出不同的结果。

使用23作为我的密钥:

异或密码 = Usx!un!dobsxqu!uihr!ldrr'fd!trhof!YNS!dobsxquhno/

异或密码2 = fAKF\V\P@JBGGZZA_VA@STWG@[]Uj|'W]QAKCFZ]]

如果有人能帮助我更好地理解这些结果,我将不胜感激!

对于第一个函数,始终使用键中的最后一个字符。这是因为每次迭代时,它都会在 for 循环中分配character,并丢弃最后一个字符,直到您迭代到最后。

对于第二个,采用明文"abc"和密钥"42""a"是用"4"加密的。 "b" "2""c"再次使用"4",就像你使用cycle()一样,所以它又回到了起点。

对于第一个函数,它与"2" "a""b""2" "c",与"2"

为了扩展列表理解,它将是这样的:

from itertools import izip, cycle
def list_comp(plaintext, key):
    return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(plaintext, cycle(key)))
def not_list_comp(plaintext, key):
    temp = []
    for x, y in izip(plaintext, cycle(key)):
        temp.append(chr(ord(x) ^ ord(y)))
    return ''.join(temp)

在第一种情况下,对于明文的每个字母,您正在对密钥的每个字符执行异或。如果执行XORcipher2('foo', 'bar')则顺序为:

chr(ord('f') ^ ord('b'))     # 'x04'
chr(ord('x04') ^ ord('a'))  # ´e´
chr(ord('e') ^ ord('r'))     # 'x17'
output += 'x17'
chr(ord('o') ^ ord('b'))     # 'r'
chr(ord('r') ^ ord('a'))    # 'e'
chr(ord('l') ^ ord('r'))     # 'x1e'
output += 'x1e'
chr(ord('o') ^ ord('b'))
chr(ord('r') ^ ord('a'))
chr(ord('l') ^ ord('r'))
output += 'x1e'

可能你真正想要的是(假设你想要一个使用itertools算法的替代方案):

def XORcipher(plaintext, key):
    output = ""
    for i, character in enumerate(plaintext):
        output += chr(ord(character) ^ ord(key[i % len(key)]))
    return output

证明:

>>> XORcipher('foo', 'bar')
'x04x0ex1d'
>>> XORcipher2('foo', 'bar')
'x04x0ex1d'

最新更新