2016-03-09 1 views
0

La simple utilisation des méthodes tobytes et frombytes ne donnera pas toujours un objet équivalent comme indiqué ci-dessous.Comment correctement sérialiser un bitarray python?

Cela semble provenir du fait que le bitarray source n'a pas une longueur divisible par huit.

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 

Répondre

0

La solution consiste à économiser la longueur et à rogner le bitarray désérialisé.

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)