【问题标题】:How to pack & unpack 64 bits of data?如何打包和解包 64 位数据?
【发布时间】:2016-02-06 18:17:58
【问题描述】:

我有一个64位的数据结构如下:

HHHHHHHHHHHHHHHGGGGGGGGGGGFFFEEEEDDDDCCCCCCCCCCCCCCBAAAAAAAAAAAA

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 是否真的按照我想要的方式工作。无论我最终实现什么模块,数据结构都将封装在一个类中,该类通过属性 getter/setter 读取和写入结构。

我还将对某些位值使用常量(或枚举),并且能够使用以下方式设置映射掩码会很方便:

# 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 位格式,这对我的应用程序来说并不理想(恕我直言)。

【问题讨论】:

  • 您接收的 64 位数据是什么格式的?字符串、字节字符串、整数值或?
  • 数据按照上面的格式检索和发送 - 本质上是一个 64 位数值,然后我通过问题中的伪 API 进行操作。
  • 所以它是一个 64 位 Python 整数中的值?
  • 我写过从较大的结构中提取位域的东西。我不记得有任何特殊模块可以提供帮助。我记得很多使用 >> 和 100% 覆盖率的单元测试库

标签: python bitvector


【解决方案1】:

根据使用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] --&gt; binary: 000000000001
set block id: current 000000000000 --&gt; 000000000001
int[1] --&gt; binary: 000000000001
BitVector[64] set block id: 000000000001 [1]
BitVector[64]: 0000000000000000000000000000000000000000000000000000000000000001

如果实用方法有改进,我非常愿意接受一些建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2016-09-22
    相关资源
    最近更新 更多