基于索引将bytes对象分成n个大小相等的块

2024-10-04 11:24:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在写一个脚本来破解一个重复的keyxor(Vigenère)密码。在

这涉及到确定一个数字(0<;n<;可能是50),然后将一个bytes对象拆分为n个较小的块,其中第一个块包含(来自原始对象)索引n、2n、3n,下一个包含n+1、2n+1、3n+1。。。然后是n+y,2n+y,3n+y,其中y<;n

如果n=3,字节[0,2,5,8等]应该在一个块中,字节[1,3,6,9]应该在下一个块中,字节[2,4,7,10]应该在最后一个块中。在

我可以用字符串很容易地实现这一点,但我不知道如何使用bytes对象。我搜索并找到并修改了以下代码:

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\u c在每个元组上。在

有什么关于字节对象的“字符串操作”的帮助吗?在

注意:我正在进行Break repeating-key XOR挑战cryptopals.com公司–我看过其他人在Github上的解决方案,但他们大多使用专门的加密模块,我想看看我所做工作的勇气。在


Tags: 对象字符串lt脚本most字节bytes整数
1条回答
网友
1楼 · 发布于 2024-10-04 11:24:02

概念上,一个bytesobject是一个整数序列:

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

。。。所以它的建造者会很乐意接受其中一个:

^{pr2}$

知道了这一点,您可以将第二行改为:

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),如果密文是keylength的精确倍数,blocks中会得到最后一个空的bytestring:

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']

相关问题 更多 >