2016-02-06 5 views
1

У меня есть структура данных 64-битный следующим образом:Как упаковать и распаковать 64 бита данных?

HHHHHHHHHHHHHHHHGGGGGGGGGGGGFFFEEEEDDDDCCCCCCCCCCCCBAAAAAAAAAAAA

A: 12 бит (без знака)
Б: 1 бит
С: 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 на самом деле работает так, как я хочу его. Независимо от того, какой модуль я в конечном итоге реализую, структура данных будет инкапсулирована в класс, который читает и записывает в структуру с помощью свойств getters/seters.

Я также буду использовать константы (или перечисления) для некоторых из битовых значений, и было бы удобно, чтобы иметь возможность установить отображенную маску, используя что-то вроде:

# 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 

Есть ли модуль Python в 3.x, который поможет мне достичь этой цели? Если BitVector будет (или должен) работать, некоторые полезные подсказки (например, примеры) будут оценены. Похоже, что BitVector хочет заставить все использовать 8-битный формат, который не идеален для моего приложения (IMHO).

+0

В каком формате вы получаете 64-битные данные? Строка, строка байтов, целочисленное значение или? – martineau

+0

Данные извлекаются и отправляются, как показано в формате выше - по существу, как 64-разрядное числовое значение, которое затем я обрабатываю с помощью псевдо API в вопросе. – IAbstract

+0

Значит, это значение в 64-битном целое число Python? – martineau

ответ

0

На основе рекомендации для использования 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

Если есть усовершенствования методов полезности, я более чем готов принять некоторые советы.

 Смежные вопросы

  • Нет связанных вопросов^_^