在Python3中,如何从字节数组的特定位提取值?

2024-09-28 23:23:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个长度为6字节(48位)的字节数组。只有每个字节的前六位是相关的。高两位不包含数据,因此应忽略它们。在转换为数字时,不应包含它们

我想从字节数组中提取一个特定范围的位,并将其转换为一个数字,同时忽略每个字节的两个高位

例如
以下面的字节数组为例:b'\x12\x08\x1c\x30\x32\x21'
第47位->;00010010 000010000110000110000 00110010 00100001<;-第0位

如果我想要位0到15的值。答案应该是3233(1+32+128+1024+2048)

00010010 00001000 00011100 00110000 00110010 00100001  
                               ^^^^ XX^^^^^^ XX^^^^^^  

       

如果我想要第6位到第12位的值。它应该是50(2+16+32)

00010010 00001000 00011100 00110000 00110010 00100001
                                  ^ XX^^^^^^ XX      

我可以在脑子里笨拙地做这件事,但我在用Python写下来时遇到了问题。这些是我认为我应该做的步骤,但我不确定这是否是最好/最简单的方法,也不确定我应该如何做

  1. 将字节数组转换为包含二进制值的单个字符串
  2. 将二进制字符串的每七个和八个字符(从右侧开始计数)更改为另一个字符(例如“-”)
  3. 从新字符串中删除任何“-”字符。[已编辑]
  4. 从二进制字符串中提取所需的位。[已编辑]
  5. 将该字符串从二进制转换为值

……所以

一,。如何将字节数组转换为48位二进制字符串?
2.是否有一种简单的方法可以将二进制字符串中的每七位和每八位更改为“-”?
5.将包含二进制值的字符串转换为数字

…我的思维过程对这有什么好处,或者有没有更简单的方法来实现这一点

我真的很感谢你在这方面的帮助

[编辑]我想我的问题中第3步和第4步的顺序不对。。。在提取二进制数字之前,我想删除不需要的位。问题经相应编辑。[/编辑]


Tags: 数据方法字符串编辑字节二进制数字数组
3条回答

这就是你要找的吗

bytes6 = bytearray([0b00010010, 0b00001000, 0b00011100, 0b00110000, 0b00110010, 0b00100001])
shift = 30 # Shift first byte this much (6 bits * 5)
result = 0
for b in bytes6:
    result |= (b & 0x3F) << shift
    shift -= 6
print(bin(result))

输出:'0b10010001000011100110000110010100001'

这就是我想到的

def bit_value(data, first_bit, last_bit):
    """ Returns a value based on what bits are set between first_bit and last_bit of a byte array, ignoring bit 7 and 8 of each byte."""

    # Convert bytes to a binary string
    number = int.from_bytes(data, "big")
    bits = f"{number:048b}"

    # Change 7th and 8th bits to "-"
    clean_bits = ""
    for i in range(0,48):
        if i % 8 == 0 or i % 8 == 1:
            clean_bits += "-"
        else:
            clean_bits += bits[i]

    # Strip out the unwanted "-"
    clean_bits = clean_bits.replace("-","")

    # Get the bits we want
    bits_i_want = clean_bits[35-first_bit:36-last_bit]

    # Get the value of the resulting binary string
    value = int(bits_i_want, 2)

    return value 

如果我正确理解您的要求,您可以尝试以下方式:

test.py:

def bit_value(data, first_bit, last_bit):
    result = ""

    for i in range(47 - last_bit, 48 - first_bit):
        byte = i // 8
        bit = 7 - (i % 8)

        if bit < 6:
            result += "01"[data[byte] >> bit & 1]

    return int(result, 2)


def main():
    data = b"\x12\x08\x1c\x30\x32\x21"

    test1 = bit_value(data, 0, 15)
    print(f"{test1:#b}, {test1}")

    test2 = bit_value(data, 6, 12)
    print(f"{test2:#b}, {test2}")


if __name__ == "__main__":
    main()

测试:

$ python test.py 
0b110010100001, 3233
0b10010, 18

相关问题 更多 >