简体   繁体   English

如何正确序列化python bitarray?

[英]How to properly serialize a python bitarray?

Simply using the tobytes and frombytes methods will not always give an equivalent object as shown below.简单地使用 tobytes 和 frombytes 方法并不总是给出如下所示的等效对象。

This seems to stem from the fact that the source bitarray does not have a length divisible by eight.这似乎源于这样一个事实,即源位数组的长度不能被八整除。

from bitarray import bitarray  # pip install bitarray


foo = bitarray('0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000010000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000010000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000010000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '000000000000000000000000000000000000000000000001000000',
               endian="little")


bar = bitarray(endian="little")
bar.frombytes(foo.tobytes())
assert(foo.tobytes() == bar.tobytes())  # passes
assert(foo == bar)  # fails

The solution is to save the length and trim the deserialized bitarray.解决方案是保存长度并修剪反序列化的位数组。

from bitarray import bitarray  # pip install bitarray
import json
from base64 import b64encode, b64decode


def serialize(ba):
    return json.dumps({
        "endian": ba.endian(),
        "bytes": b64encode(ba.tobytes()),
        "len": len(ba)
    })


def deserialize(data):
    data = json.loads(data)
    ba = bitarray(endian=data["endian"])
    ba.frombytes(b64decode(data["bytes"]))
    return ba[:data["len"]]


foo = bitarray('0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000010000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000010000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000010000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '0000000000000000000000000000000000000000000000000000000000'
               '000000000000000000000000000000000000000000000001000000',
               endian="little")


bar = deserialize(serialize(foo))
assert(foo.tobytes() == bar.tobytes())
assert(foo == bar)

You can save and load a bitarray directly with bitarray python module您可以使用 bitarray python 模块直接保存和加载位数组

# Save bitarray
ba = bitarray('11100000')
with open('bitarray.bin', 'wb') as f:
        ba.tofile(f)

# Load bitarray
ba = bitarray()
with open('bitarray.bin', 'rb') as f:
        ba.fromfile(f)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM