当使用 python 的 struct.pack 打包字节时,我很惊讶虽然我的 byte 顺序是小端,但我的 位 顺序似乎是大端。我的最高有效字节出现在下面输出的右侧,但每个字节的最高有效位出现在左侧。 (我使用 bitstring 中的 BitArray 来显示位。)
In[23]: BitArray(struct.pack('B', 1)).bin
Out[23]:'00000001'
In[24]: BitArray(struct.pack('H', 1)).bin
Out[24]:'0000000100000000'
In[25]: sys.byteorder
Out[25]:'little'
这让我感到惊讶,因为我读过 here “位顺序通常遵循与给定计算机系统的字节顺序相同的字节顺序。也就是说,在大端系统中,最高有效位存储在最低位地址中;在小端系统中,最低有效位是存储在最低位地址。”
我的位顺序与此处的字节顺序相反,我的解释是否正确?
此外,我知道您可以使用 >
更改字节顺序和<
,但我想没有办法改变位顺序?
编辑:对于上下文,现在我正在编写一个与 ATI NetFT 传感器进行 TCP 通信的 Python 实现,该实现基于从 B - 76 页开始的协议(protocol)描述 here 。但是,在我使用各种传感器实现串行和网络通信的工作中,经常出现同样的问题。在这种情况下,协议(protocol)描述如下:将字节 16 的位 2 设置为 1 以偏置传感器,并且我发现 python 中的位 0 与控制偏置的位 0 不对应 - 该位字节顺序似乎颠倒了。
最佳答案
不,Python 没有提供反转位顺序的方法 - 但您不需要这样做。这篇文章让你过于偏执;-)
字节顺序的字节序通常对软件来说是不可见的。例如,如果您在 C 中读取 2 字节的短字节,则无论物理存储约定如何,底层硬件都会提供大端结果。存储 258 (0x0102) 并读回 258,无论存储的物理字节顺序如何。区分差异的唯一方法是在小于 N 字节的 block 中读取(或写入)N 字节值的一部分。这在网络协议(protocol)和可移植存储格式中很常见,但在这些之外很少见。
类似地,检测物理位顺序的字节顺序的唯一方法是机器是否可位寻址,这样您就可以一次直接读取一位。我不知道当前有哪台机器支持位寻址,即使有这样一个野兽 C 也不支持直接位级访问。如果您一次读取一个字节,则无论物理位存储顺序如何,硬件都会再次以大端位顺序传递字节。
例如,如果您一次插入位级串行端口,那么您需要了解特定硬件所需的约定。但在这种情况下 struct.pack() 无论如何都是无用的 - struct.pack() 操作的最小单位是一个字节,并且在那个硬件级的位级排序是不可见的。例如,您的 struct.pack('B', 1)
将解压为 1,无论运行它的计算机的位级字节序如何。
代码位
由于“一般原则”在这里似乎还不够,并且没有提供可使用的具体代码,因此这里有一些可能有用的代码。
正如评论中提到的,如果你想反转一个字节的位顺序,最简单、最快的方法是预先计算一个包含 256 个项目的列表,将一个字节映射到它的位反转值:
br = [int("{:08b}".format(i)[::-1], 2) for i in range(256)]
assert sorted(br) == list(range(256))
那么,例如,
>>> br[0], br[1], br[2], br[254], br[255]
(0, 128, 64, 127, 255)
如果您使用 bytes
对象,.translate()
方法可以使用此表(在将其转换为 bytes
object)通过一次调用转换整个对象:
reverse_table = bytes(br)
然后,例如,
>>> original = bytes([0, 1, 2, 3, 254, 255])
>>> print([i for i in original.translate(reverse_table)])
[0, 128, 64, 192, 127, 255]
如果您一次构建一点字节(如“将字节 16 的位 2 设置为 1”),则可以从一开始就以“相反的顺序”(在适当的情况下)构建它们。要以LSB 0
顺序构建字节,“设置位i”意味着
byte |= 1 << i
要以 MSB 0
顺序构建字节,则为
byte |= 1 << (7-i)
但是,如果不知道您正在使用的 API 的具体细节以及您喜欢的工作方式,就不可能猜测出您需要的具体代码。
关于python - python struct.pack 中的位顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47373255/