简体   繁体   English

如何将字节数组中的每 n 位解压缩为整数数组

[英]how to unpack every n bits from a byte array into an integer array

data comes from a binary file, and I convert it to a byte_array using numpy as below: data来自二进制文件,我使用 numpy 将其转换为 byte_array,如下所示:

byte_array = np.frombuffer(data, dtype=np.uint8)

Is there any convenient way to extract every n bits (8<=n<=20) from this byte_array then cast those n bits to an integer and store all the integers in an array?有没有什么方便的方法可以从这个byte_array中提取每 n 位(8<=n<=20),然后将这些 n 位转换为整数并将所有整数存储在一个数组中?

The only way that I can think of is to go through the byte_array one by one, extract a full byte first, if the total bits extracted so far is less than n, extract the remaining bits, then concatenate with the first byte and form an output integer, store that integer to the output array.我能想到的唯一方法是byte_array ,首先提取一个完整的字节,如果到目前为止提取的总位数小于n,则提取剩余的位,然后与第一个字节连接并形成一个输出整数,将该整数存储到输出数组。

For example, n = 12, byte_array[0:3] = 123, 99, 100例如,n = 12, byte_array[0:3] = 123, 99, 100

output_integer[0] = 123 | ((99&0xF)<<8) # bits 0..7 from 123 and bits 8..11 from the lower 4 bits of 99 
output_integer[1] = (99>>4) | (100<<4) # bits 0..3 from higher 4 bits of 99 and bits 4..11 from 100

You can create a generator for yielding the bits and use for example more_itertools.chunked to process the bit stream in n-chunks:您可以创建一个生成器来产生位,并使用例如more_itertools.chunked来处理 n-chunks 中的位流:

from more_itertools import chunked

def get_bits(data):
    for b in data:
        yield from f'{bin(b)[2:]:0>8}'

data = b'0123456789'
n = 20
for bits in chunked(get_bits(data), n):
    print(int(''.join(bits), base=2))

In the above example, if (r := len(data)*8 % n) != 0 then the last bits will be of length r < n .在上面的示例中,如果(r := len(data)*8 % n) != 0 bits最后一位的长度将是r < n If that is undesired, you can either pad the bit stream beforehand on the left (ie at the start), which requires knowledge of its length, or use for example more_itertools.grouper to pad it on the right (ie at the end).如果不希望这样,您可以预先在左侧(即在开始时)填充比特流,这需要知道它的长度,或者使用例如more_itertools.grouper在右侧(即在末尾)填充它。

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

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