Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 根据索引将字节对象拆分为n个大小相等的块_Python_Python 3.x_Cryptography_Byte - Fatal编程技术网

Python 根据索引将字节对象拆分为n个大小相等的块

Python 根据索引将字节对象拆分为n个大小相等的块,python,python-3.x,cryptography,byte,Python,Python 3.x,Cryptography,Byte,我正在写一个脚本来破解重复密钥XOR(Vigenère)密码 这涉及到确定一些数字(0

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

这涉及到确定一些数字(0 如果n=3,字节[0,2,5,8等]应在一个块中,字节[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上进行挑战——我看过其他人在Github上的解决方案,但他们大多使用专门的加密模块,我想看看我在做什么。

从概念上讲,
字节
对象是一个整数序列:

>>> 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))]
…您将返回
字节
对象:

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)
,如果密文是
keydlength
的精确倍数,则在
块中会得到一个最终的空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 = [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']