python - python struct.pack 中的位顺序

标签 python struct endianness

当使用 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/

相关文章:

ios - 计算 iOS 的 CoreMIDI 弯音值?

python - 将一个函数的所有参数传递给另一个函数

Python:根据 boolean 条件消除 Pandas DataFrame 中的行

c++ - 为结构成员分配的内存是连续的吗?如果结构成员是数组怎么办?

c++ - &y[0] == &x.a 的值是多少?

c - 使用字节重新排序的位移位方法时,按位与 255 的意义何在?

go - 在 rune 上调用 uint16 是大端还是小端?

python - 通过 Gunicorn 上传 Flask 和 NGINX 流式文件

python - 在Scrapy(网络爬虫)中返回复杂的项目

c - 用多线程修改一个结构c编程