我一直在寻找重复密钥XOR密码的代码,我无法掌握代码的一些功能。根据我的理解,密钥的每个字节应该与字符串消息的每个字节一起使用,并且应该在它们之间应用XOR操作。要做到这一点,你似乎只需要迭代字符串的长度,遍历键的每个字节并应用XOR操作。
由于某种原因,代码使用生成器函数(在另一个函数内部)循环键。函数的一个实例被创建并保存在一个变量中,然后将该变量与消息的字节值列表一起压缩,然后应用XOR操作。
我没有得到的是,因为这个函数循环while TRUE
zip函数如何在两个列表之间的每对字节之间产生元组?也许我误解了发电机的功能,但这可以解决吗?
这是功能:
def mc_part5():
def cycle_key(key):
idx = 0
while True:
yield ord(key[idx%len(key)])
idx += 1
g = cycle_key('ICE')
s = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"
hh = bytes(s,'ascii')
xored = bytes([a^b for (a,b) in zip(hh, g)])
c = '0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f'
expected = bytes.fromhex(c)
assert( xored == expected )
答案 0 :(得分:2)
我认为你不知道生成器是如何工作的,而是zip
如何工作。你在那里定义的生成器可以永远循环是完全正确的 - 但是,当最短的输入可迭代用尽时,zip
将停止产生元组。例如(在python2.x上):
>>> def count():
... i = 0
... while True:
... yield i
... i += 1
...
>>> zip(count(), 'foo')
[(0, 'f'), (1, 'o'), (2, 'o')]
在这种情况下,两个迭代中较短的一个是字符串(hh
),因为g
具有无限长度。
就清理而言......可能没有那么好,但你可以使用itertools.cycle
和生成器表达式:
g = (ord(c) for c in itertools.cycle('ICE'))
这减少了所有模数无意义,这让事情变得更加艰难。