2015-12-14 33 views
0

我一直在尋找重複密鑰異或密碼的代碼,我無法掌握代碼的某些功能。據我所知,密鑰的每個字節應該與字符串消息的每個字節一起使用,並且應該在它們之間應用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) 

回答

2

我認爲你困惑不是發電機的工作原理,但如何zip作品。你完全正確的是,那裏定義的生成器可以永久循環 - 但是,當最短的輸入迭代耗盡時,zip將停止產生元組。例如(上python2.x):

>>> def count(): 
... i = 0 
... while True: 
...  yield i 
...  i += 1 
... 
>>> zip(count(), 'foo') 
[(0, 'f'), (1, 'o'), (2, 'o')] 

在這種情況下,兩個iterables的短是因爲g字符串(hh)具有無限的長度。

至於清理......它可能不是好多了,但你可以使用itertools.cycle和發電機的表達:

g = (ord(c) for c in itertools.cycle('ICE')) 

這削減了所有的模量廢話,這使得事情有點強硬來的神交。