生成器用于重复密钥XOR密码时的混淆

时间:2015-12-14 03:24:34

标签: python encryption generator

我一直在寻找重复密钥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 )

1 个答案:

答案 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'))

这减少了所有模数无意义,这让事情变得更加艰难。