十六进制字节的正确解释,转换i

2024-10-03 23:23:48 发布

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

我正在尝试通过RS485连接电表。 到目前为止,它工作得很好,除了我有问题读取什么仪表写回RS485线。在

我知道电表上的数据是正确的,因为我可以用Docklight和制造商的内部程序读取。在

所以我唯一的问题是我要返回的十六进制字节的转换。在

我正在接收

>>> b'\x01\x03\x04Ce/\xec\xe2'

这应该是8或9个十六进制字节。 我希望收到类似

^{pr2}$

问题似乎是python以“ASCII”来解释它,不管它能解释什么,我不能进一步转换它,因为它是非十六进制数字。 我得到的错误是

>>> binascii.Error: Non-hexadecimal digit found`

当我从另一个角度看的时候。 我正在发送

>>> data=bytearray([0x01,0x03,0x4A,0x38,0x00,0x02,0x53,0xDE])

显示为

>>> bytearray(b'\x01\x03J8\x00\x02S\xde')

当我打印的时候

那么,我如何告诉python-3,我想看到的是8个十六进制字节,而不是他自动进行的一些解释呢?我相信我错过了一件很容易的事,一旦你知道去哪里找。在

我想把字节4,5,6,7转换成浮点。但是因为它显示的是非十六进制数字,所以我不能这样做。在


Tags: 数据程序字节仪表数字xe2x03x01
2条回答

Ce/也是字节;它们是ASCII字符,因此不需要用\x..十六进制转义符来显示。在

您也不需要解码\x..十六进制转义符,它们只是Python为您提供bytes对象的调试表示;每个字节要么显示为转义序列,要么显示为可打印的ASCII字母。在

同样的情况也会发生在你的类似的例子中:

>>> b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68'
b'\x01\x03\x04Cg\x81\xecCh'

这是完全相同的值,但是\x68是ASCII字母h,等等

输出是bytes对象的默认repr()输出。它不能改变。如果需要不同的输出,则必须编写自己的代码。在

您可以使用binascii.hexlify()函数将所有字节显示为十六进制,例如:

^{pr2}$

现在您有了一个bytes字符串,其中包含十六进制字符。或者您可以使用str.join()函数,将每个字节转换为十六进制,前缀为\x文本:

>>> ''.join(r'\x{:02x}'.format(byte) for byte in b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68')

\X604\X603\X603\X76\X76\

>>> print(''.join(r'\x{:02x}'.format(byte) for byte in b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68'))
\x01\x03\x04\x43\x67\x81\xec\x43\x68

这是一个str对象,以\x和十六进制数字作为字符。在

注意,这只是显示值。值没有改变;字节都在那里,不管你怎么显示它们。如果需要将4个字节转换为浮点,则只需将这4个字节转换为:

struct.unpack('f', yourbytes[4:])  # 4 bytes for C float in native order

它使用^{} module直接使用字节。不需要十六进制表示:

>>> import struct
>>> struct.unpack('f', b'\x01\x03\x04Ce/\xec\xe2'[:4])
(132.01173400878906,)

您可以使用struct.unpack()从数据中获取数字。方法如下:

In [171]: import struct

In [190]: b2
Out[190]: b'\x01\x03J8\x00\x02S\xde'

In [191]: struct.unpack('B'*len(b2), b2)
Out[191]: (1, 3, 74, 56, 0, 2, 83, 222)

In [192]: [*map(hex, struct.unpack('B'*len(b2), b2))]
Out[192]: ['0x1', '0x3', '0x4a', '0x38', '0x0', '0x2', '0x53', '0xde']

相关问题 更多 >