簡體   English   中英

根據索引將字節對象分成 n 個大小相等的塊

[英]Break bytes object into n equally sized blocks based on index

我正在編寫一個腳本來破解重復密鑰 XOR (Vigenère) 密碼。

這涉及確定某個數字(0 < n < 可能是 50),然后將字節對象拆分為 n 個較小的塊,其中第一個塊包含(來自原始對象)索引 n、2n、3n,下一個包含 n+1、2n +1, 3n+1... 然后是 n+y, 2n+y, 3n+y 其中 y < n。

如果 n = 3,字節 [0, 2, 5, 8 etc] 應該在一個塊中,字節 [1,3,6,9] 在下一個塊中,字節 [2,4,7,10] 在下一個塊中最后塊。

我可以用字符串輕松實現這一點,但我不知道如何使其與字節對象一起使用。 我搜索並找到並修改了此代碼:

blocks = [ciphertext[i:i+most_likely_keylength] for i in range(0, len(ciphertext)+1, most_likely_keylength)]

transposedBlocks = list(zip_longest(*blocks, fillvalue=0))

##ciphertext is a bytes object resulting from the following line:
##ciphertext = base64.b64decode(open('Q6.txt', 'r').read())

然而,這會返回一個由整數填充的元組列表,我不知道如何再次“連接”這些整數,因此它們將是像以前一樣的長二進制對象。 (這樣我就可以在每個元組上運行像 Crypto.Util.strxor_c 這樣的好東西。

對字節對象的這種“字符串操作”有幫助嗎?

注意:我正在 cryptopals.com 上進行Break repeating-key XOR挑戰——我在 Github 上看過其他人的解決方案,但他們大多使用專門的加密模塊,我想看看我在做什么。

從概念上講, bytes對象一個整數序列:

>>> tuple(b'ciphertext')
(99, 105, 112, 104, 101, 114, 116, 101, 120, 116)

...所以它的構造函數會很樂意接受一個:

>>> bytes((99, 105, 112, 104, 101, 114, 116, 101, 120, 116))
b'ciphertext'

知道了這一點,您可以將第二行更改為:

transposed = [bytes(t) for t in zip_longest(*blocks, fillvalue=0))]

...你會得到bytes對象:

from itertools import zip_longest

ciphertext = b'ciphertext'
keylength = 3

blocks = [ciphertext[i:i+keylength] for i in range(0, len(ciphertext)+1, keylength)]
# [b'cip', b'her', b'tex', b't']

transposed = [bytes(t) for t in zip_longest(*blocks, fillvalue=0)]
# [b'chtt', b'iee\x00', b'prx\x00']

但是,您的代碼中有一個錯誤——因為您在調用range()使用的是len(ciphertext)+1而不僅僅是len(ciphertext) ,如果密文是一個精確的倍數,您將得到一個blocks的最終空字節串keylength

ciphertext = b'SplitsEvenly'

blocks = [ciphertext[i:i+keylength] for i in range(0, len(ciphertext)+1, keylength)]
# [b'Spl', b'its', b'Eve', b'nly', b'']

...這導致在transposed中所有元素的末尾有額外的空字節:

transposed = [bytes(t) for t in zip_longest(*blocks, fillvalue=0)]
# [b'SiEn\x00', b'ptvl\x00', b'lsey\x00']

如果你刪除+1 ,它在兩種情況下都能正常工作:

ciphertext = b'ciphertext'

blocks = [ciphertext[i:i+keylength] for i in range(0, len(ciphertext), keylength)]
# [b'cip', b'her', b'tex', b't']

transposed = [bytes(t) for t in zip_longest(*blocks, fillvalue=0)]
# [b'chtt', b'iee\x00', b'prx\x00']
ciphertext = b'SplitsEvenly'

blocks = [ciphertext[i:i+keylength] for i in range(0, len(ciphertext), keylength)]
# [b'Spl', b'its', b'Eve', b'nly']

transposed = [bytes(t) for t in zip_longest(*blocks, fillvalue=0)]
# [b'SiEn', b'ptvl', b'lsey']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM