如何打包和解包 64 位数据?
How to pack & unpack 64 bits of data?
我有一个64位的数据结构如下:
HHHHHHHHHHHHHHHHGGGGGGGGGGGGFFFEEEEDDDDCCCCCCCCCCCCBAAAAAAAAAAAA
A:12 位(无符号)
B: 1 位
C: 12 位(无符号)
D: 4 位(无符号)
E: 4 位(无符号)
F: 3 位(无符号)
G:12 位(无符号)
H:16 位(无符号)
使用 Python,我试图确定我应该使用哪个模块(最好是本机 Python 3.x)。我正在查看 BitVector,但无法弄清楚一些事情。
为了便于使用,我希望能够执行如下操作:
# To set the `A` bits, use a mapped mask 'objectId'
bv = BitVector(size=64)
bv['objectId'] = 1
我不确定 BitVector 是否真的按照我想要的方式工作。无论我最终实现什么模块,数据结构都将封装在一个 class 中,该 class 通过 属性 getters/setters 读取和写入该结构。
我还将为某些位值使用常量(或枚举),并且能够使用类似以下内容设置映射掩码会很方便:
# To set the 'B' bit, use the constant flag to set the mapped mask 'visibility'
bv['visibility'] = PUBLIC
print(bv['visibility']) # output: 1
# To set the 'G' bits, us a mapped mask 'imageId'
bv['imageId'] = 238
3.x 中是否有一个 Python 模块可以帮助我实现这个目标?如果 BitVector 将(或应该)工作,一些有用的提示(例如示例)将不胜感激。似乎 BitVector 想要将所有内容都强制为 8 位格式,这对我的应用程序来说并不理想(恕我直言)。
根据使用 bitarray 的建议,我用两种实用方法提出了以下实现:
def test_bitvector_set_block_id_slice(self):
bv = bitvector(VECTOR_SIZE)
bv.setall(False)
print("BitVector[{len}]: {bv}".format(len=bv.length(),
bv=bv.to01()))
print("set block id: current {bid} --> {nbid}".format(bid=bv[52:VECTOR_SIZE].to01(),
nbid=inttobitvector(12, 1).to01()))
# set blockVector.blockId (last 12 bits)
bv[52:VECTOR_SIZE] = inttobitvector(12, 1)
block_id = bv[52:VECTOR_SIZE]
self.assertTrue(bitvectortoint(block_id) == 1)
print("BitVector[{len}] set block id: {bin} [{val}]".format(len=bv.length(),
bin=block_id.to01(),
val=bitvectortoint(block_id)))
print("BitVector[{len}]: {bv}".format(len=bv.length(),
bv=bv.to01()))
print()
# utility methods
def bitvectortoint(bitvec):
out = 0
for bit in bitvec:
out = (out << 1) | bit
return out
def inttobitvector(size, n):
bits = "{bits}".format(bits="{0:0{size}b}".format(n,
size=size))
print("int[{n}] --> binary: {bits}".format(n=n,
bits=bits))
return bitvector(bits)
输出结果如下:
BitVector[64]: 0000000000000000000000000000000000000000000000000000000000000000
int[1] --> binary: 000000000001
set block id: current 000000000000 --> 000000000001
int[1] --> binary: 000000000001
BitVector[64] set block id: 000000000001 [1]
BitVector[64]: 0000000000000000000000000000000000000000000000000000000000000001
如果对实用方法有改进,我非常愿意接受一些建议。
我有一个64位的数据结构如下:
HHHHHHHHHHHHHHHHGGGGGGGGGGGGFFFEEEEDDDDCCCCCCCCCCCCBAAAAAAAAAAAA
A:12 位(无符号)
B: 1 位
C: 12 位(无符号)
D: 4 位(无符号)
E: 4 位(无符号)
F: 3 位(无符号)
G:12 位(无符号)
H:16 位(无符号)
使用 Python,我试图确定我应该使用哪个模块(最好是本机 Python 3.x)。我正在查看 BitVector,但无法弄清楚一些事情。
为了便于使用,我希望能够执行如下操作:
# To set the `A` bits, use a mapped mask 'objectId'
bv = BitVector(size=64)
bv['objectId'] = 1
我不确定 BitVector 是否真的按照我想要的方式工作。无论我最终实现什么模块,数据结构都将封装在一个 class 中,该 class 通过 属性 getters/setters 读取和写入该结构。
我还将为某些位值使用常量(或枚举),并且能够使用类似以下内容设置映射掩码会很方便:
# To set the 'B' bit, use the constant flag to set the mapped mask 'visibility'
bv['visibility'] = PUBLIC
print(bv['visibility']) # output: 1
# To set the 'G' bits, us a mapped mask 'imageId'
bv['imageId'] = 238
3.x 中是否有一个 Python 模块可以帮助我实现这个目标?如果 BitVector 将(或应该)工作,一些有用的提示(例如示例)将不胜感激。似乎 BitVector 想要将所有内容都强制为 8 位格式,这对我的应用程序来说并不理想(恕我直言)。
根据使用 bitarray 的建议,我用两种实用方法提出了以下实现:
def test_bitvector_set_block_id_slice(self):
bv = bitvector(VECTOR_SIZE)
bv.setall(False)
print("BitVector[{len}]: {bv}".format(len=bv.length(),
bv=bv.to01()))
print("set block id: current {bid} --> {nbid}".format(bid=bv[52:VECTOR_SIZE].to01(),
nbid=inttobitvector(12, 1).to01()))
# set blockVector.blockId (last 12 bits)
bv[52:VECTOR_SIZE] = inttobitvector(12, 1)
block_id = bv[52:VECTOR_SIZE]
self.assertTrue(bitvectortoint(block_id) == 1)
print("BitVector[{len}] set block id: {bin} [{val}]".format(len=bv.length(),
bin=block_id.to01(),
val=bitvectortoint(block_id)))
print("BitVector[{len}]: {bv}".format(len=bv.length(),
bv=bv.to01()))
print()
# utility methods
def bitvectortoint(bitvec):
out = 0
for bit in bitvec:
out = (out << 1) | bit
return out
def inttobitvector(size, n):
bits = "{bits}".format(bits="{0:0{size}b}".format(n,
size=size))
print("int[{n}] --> binary: {bits}".format(n=n,
bits=bits))
return bitvector(bits)
输出结果如下:
BitVector[64]: 0000000000000000000000000000000000000000000000000000000000000000
int[1] --> binary: 000000000001
set block id: current 000000000000 --> 000000000001
int[1] --> binary: 000000000001
BitVector[64] set block id: 000000000001 [1]
BitVector[64]: 0000000000000000000000000000000000000000000000000000000000000001
如果对实用方法有改进,我非常愿意接受一些建议。