如何快速制作字节数组的切片内存视图?

时间:2018-07-29 15:31:48

标签: python arrays buffer memoryview

请考虑在Python中执行此假设任务:对于ByteArray中的某些数据,计算前16个字节的SHA256哈希并将其附加到原始ByteArray中。像这样:

ba = bytearray(...)
hash = hashlib.sha256(ba[:16]).digest()
ba.extend(hash)

到目前为止一切都很好。但是切片ba[:16]用数据副本创建了一个新的ByteArray,我想避免不必要的复制。因此,使用MemoryView似乎是一个好主意:

ba = bytearray(...)
slice = memoryview(ba[:16])
hash = hashlib.sha256(slice).digest()
ba.extend(hash)

但是,等等,extend应该自a ByteArray that has an active MemoryView cannot be resized起已经提出BufferError。原来是为切片创建了一个新的ByteArray,而MemoryView不在此匿名的新ByteArray上,而不是原来的ByteArray上,所以毕竟创建了一个副本。

要正确避免复制,我必须这样做:

ba = bytearray(...)
mv = memoryview(ba)
slice = mv[:16]
hash = hashlib.sha256(slice).digest()
mv.release()
slice.release()
ba.extend(hash)

...这很丑。可以使用MemoryView的上下文管理器语法对其进行一些清理:

ba = bytearray(...)
with memoryview(ba) as mv, mv[:16] as slice:
    hash = hashlib.sha256(slice).digest()
ba.extend(hash)

但是仍然让我感到烦恼的是,必须创建两个MemoryView,然后再释放它们,以避免复制ByteArray的一部分。这是我能做的最好的事情吗?有没有更直接的方法来创建ByteArray切片的MemoryView?

(提示此问题的真正任务是为二进制协议编写实现。规范的一部分实际上确实需要为消息的一部分计算哈希并将其附加到同一消息,因此提出了假设任务以上不是太人为设计。)

0 个答案:

没有答案