2017-01-24 53 views
0

這是一個我正在使用的現代密碼學課程。單字節XOR密碼(python)

挑戰是cryptopals挑戰3:單字節XOR密碼,我試圖用python 3來幫助完成這個。

我知道我應該異或字符串並轉換爲英文。十六進制字符串是「1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736」,它以十進制形式轉換爲「806748453371902409051174291875458592743800337585421566549206796642836053682239286」。

我已經與多個十六進制字節組合(2個十六進制數字)進行XOR,但我不知道如何將其轉換爲英文。這只是蠻力和教育猜測嗎?

我知道ETAOIN SHRDLU,但這並沒有真正的幫助。

謝謝你的時間和幫助。


新增: 此外,我試圖挑戰#4但是這個代碼似乎並沒有工作。但它確實爲挑戰#3工作,所以我感到困惑。

Challenge #3 Challenge #4

+0

你有解密密碼的密鑰嗎? – bzimor

+0

有256個可能的密鑰。它是兩個十六進制字符的任意組合。我已經嘗試了一堆,但我不知道要選什麼才能選擇一個密鑰。 –

回答

2

大廈@ falsetru的回答,但只顯示已解碼的字符串最空格字符:

>>> encoded = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736' 
>>> import binascii 
>>> nums = binascii.unhexlify(encoded) 
>>> strings = (''.join(chr(num^key) for num in nums) for key in range(256)) 
>>> max(strings, key=lambda s: s.count(' ')) 
"Cooking MC's like a pound of bacon" 

而是包括空格,你可以使用ETAOIN SHRDLU(「頻率的大致順序在英語中使用12個最常用的字母「),但在這裏沒有必要。

順便說一句,我認爲如果你已經鏈接到the challenge就會很好。


編輯:或者,你可以嘗試找到鑰匙(或幾個最有前途的鍵),然後只使用該密鑰(或那幾個鍵)進行解碼。例如,假設計數的空間將決出勝負:

>>> encoded = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736' 
>>> import binascii 
>>> nums = binascii.unhexlify(encoded) 
>>> key = max(nums, key=nums.count)^ord(' ') 
>>> ''.join(chr(num^key) for num in nums) 
"Cooking MC's like a pound of bacon" 

這甚至可以很容易地通過手工來完成(儘管挑戰告訴你不這樣做)。

+0

注意。我將來會這樣做。你會如何使用ETAOIN SHRDLU來衡量角色?我本來應該親自找到鑰匙。 –

+1

@PhillipSloan誰說你應該用手工做?不是挑戰。挑戰恰恰相反,你不會**手工操作。對於體重,我只注意到,如果我只是使用12個字母,不包括中間的空間,就像我昨天做的那樣,實際上我無法將正確的結果作爲最高值的字符串... –

+0

Ohhhh ok。我完全誤解了它。我認爲它的意思是「手工完成,不要寫代碼來爲你做。」謝謝你的澄清。標點符號很重要。 –

3

您可以使用binascii.hexlifybinascii.unhexlify爲字節字符串轉換爲十六進制數,反之亦然:

>>> import binascii 
>>> binascii.hexlify(b'HELLO') # to Hex 
b'48454c4c4f' 
>>> binascii.unhexlify('48454c4c4f') # from Hex 
b'HELLO' 

使用str.isprintable,就可以過濾掉非打印考生:

>>> 'abcd'.isprintable() 
True 
>>> '\x00'.isprintable() 
False 
>>> '\x7f'.isprintable() 
False 

import binascii 

encoded = binascii.unhexlify('1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736') 
for xor_key in range(256): 
    decoded = ''.join(chr(b^xor_key) for b in encoded) 
    if decoded.isprintable(): 
     print(xor_key, decoded) 
+0

您可以使用ETAOIN SHRDLU來查找正確的解碼消息。 –

+1

這是使用上面的代碼得到的答案:烹飪MC就像一斤臘肉 – bzimor

+0

@StefanPochmann,我試過並發現'ETAOIN SHRDLU'不是一條消息。 – falsetru