2017-01-24 3 views
0

これは私が現在使っている最新の暗号クラスです。シングルバイトXOR暗号(Python)

難問はcryptopals challenge 3:Single-Byte XOR Cipherであり、これを完成させるためにPython 3を使用しようとしています。

私は文字列をXORして英語に変換することになっていることを知っています。 16進文字列は、 "806748453371902409051174291875458592743800337585421566549206796642836053682239286"に10進数形式で変換される "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"です。

複数の16進バイトの組み合わせ(2桁の16進数)に対してこれをXORしましたが、これを英語に変換する方法はわかりません。それは単なるブルートフォースであり、この時点で教育された推測ですか?

私はETAOIN SHRDLUについて知っていますが、これは本当に役立たずです。

ありがとうございました。


を追加しました: また、私はチャレンジ#4を試してみましたが、このコードが動作するようには思えません。しかし、それはチャレンジ#3のために働いたので、私は混乱しています。

Challenge #3 Challenge #4

+0

復号化のための鍵がありますか? – bzimor

+0

可能なキーは256個あります。 2つの16進文字の任意の組み合わせです。私はそれらの束を試しましたが、私はキーを選ぶために何を探すべきか分かりません。 –

答えて

2

ビルが、ほとんどのスペース文字とちょうどデコードされた文字列を示す:代わりにスペースを数えるの

>>> 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の文字のうちの1つ)を重み付けに使用しますが、ここでは必要ありません。

Btw、あなたが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を使用することができます。str.isprintableを使用して

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

は、あなたが非印刷可能な候補者を除外することができます。

>>> 'abcd'.isprintable() 
True 
>>> '\x00'.isprintable() 
False 
>>> '\x7f'.isprintable() 
False 
@のfalsetruの答えに
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