【问题标题】:Break bytes object into n equally sized blocks based on index根据索引将字节对象分成 n 个大小相等的块
【发布时间】:2015-06-01 02:21:55
【问题描述】:

我正在编写一个脚本来破解重复密钥 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 上处理 Break repeating-key XOR 挑战 – 我在 Github 上查看过其他人的解决方案,但他们大多使用专门的加密模块,我想看看我在做什么.

【问题讨论】:

    标签: python python-3.x cryptography byte


    【解决方案1】:

    从概念上讲,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']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-29
      • 2015-07-23
      • 2011-07-28
      相关资源
      最近更新 更多