Python:如何从字节中提取特定位?

21

我有一条信息,内容为 14 09 00 79 3d 00 23 27。通过调用 message[4],可以从该消息中提取每个字节,例如会得到 3d。如何从这个字节中提取单独的8位?例如,如何将24-27位作为单独的消息获取?28位呢?


你是在问如何在Python中表示一个16进制整数为2进制,还是在问如何提取一个数字的某些位?或者两者都要,提取特定位并以二进制形式显示? - jacoblaw
那个消息的数据类型是什么?请提供一个Python字面值。 - Stefan Pochmann
2个回答

45

回答你问题的第二部分,你可以通过位运算得到特定的比特值。

# getting your message as int
i = int("140900793d002327", 16)

# getting bit at position 28 (counting from 0 from right)
(i >> 28) & 1

# getting bits at position 24-27
bin((i >> 24) & 0b111)

1
@StefanPochmann 假定是将相关比特位移至整数的开头。相比于 3B 00 00 00,使用 3B 更加麻烦。 - TemporalWolf
@TemporalWolf 那不是我想表达的意思。请查看更新后的回答,了解我的真实意图。 - Stefan Pochmann
1
@TemporalWolf 呃?那不是他们改变的内容。 - Stefan Pochmann
2
重点是:我想获取位置24、25和26的三个位值,为了做到这一点,我的想法是将位移位,使位置变为0、1和2,然后使用一个数字进行AND操作,该数字在位置0、1和2上为1,在其他位置上为0。我本可以只写i>>24 & 7,但我认为用二进制写会更清晰明了。 - Anis
哦,这就解释了!非常感谢。如果我想获取30-35位,那么我应该使用i >> 30 & 0b111111,对吗?这样可以获取第30、31、32、33、34和35位的比特。 - Aditya Salapaka
显示剩余6条评论

5

最简单的方法是使用 & 运算符。使用 int(str_msg, 16) 将您的消息转换为整数。使用 bin(myint) 将整数转换为二进制字符串。

要获取字节中左侧第4-6位(从左往右数):

>> msg = int("10110111", 2) # or 0b10110111
>> extractor = int("00011100", 2) # or 0b10110111
>> result = msg & extractor
>> print bin(result)
00010100

如果您愿意,可以使用result >> 2进行位移。 显然,您会希望使这更加动态化,但这只是一个简化的示例。

2
在二进制中输入28比十进制更容易。使用“0b11100”可以更清楚地确定您想要哪些位。 - jacoblaw
不确定新版本是更好还是更糟。为什么不使用@jacoblaw展示的内容呢? - Stefan Pochmann
这只是一个例子。那个人并不是在问如何获取输入,而是结果。他如何获取输入取决于他自己。我相信他已经知道了。 - Ian Kirkpatrick
@IanKirkpatrick 我只是提到这个方法,因为似乎你不知道在Python中输入二进制的方式,如果我有冒犯之处请见谅。但我的意思并不是将二进制的字符串表示转换为整数,而是使用msg = 0b10110111。你也可以用类似的方式处理十六进制,例如test = 0xFF。在某些情况下,这样做可以使代码更易于理解。 - jacoblaw
1
@jacoblaw 那种 int("...", 2) 的方式也不够高效,因为它是在运行时计算而不是编译时。这可能并不重要,但仍然是所有方面都更差。 - Stefan Pochmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接