【问题标题】:Python format hex numberPython 格式十六进制数
【发布时间】:2021-11-20 21:08:39
【问题描述】:

我需要通过 tcp 发送一个字符串。字符串的第一部分之一是命令变量的长度

Example:
command = STATUS?UPDATE

我需要在下面发送以下字符串

sendCommand = '\x00\x00\x00'+STRINGLENGTH+'\x02'+command+'\x0D\x0A'

我的字符串长度是 11,所以我需要 STRINGLENGTH 是 11 的十六进制等效值,即 0xB,除了我需要它输出为 \x0B

用前导 0 填充它很容易,但我无法将其输出为 \x 而不是 0x,如果我进行字符串替换,则会对其进行处理作为文本而不是十六进制,所以它不起作用。

我的最终十六进制字符串应该是:

\x00\x00\x00\x0B\x02\x53\x54\x41\x54\x55\x53\x3f\x55\x53\x45\x52\x0D\x0A

我反而得到:

\x00\x00\x000x0B\x02\x53\x54\x41\x54\x55\x53\x3f\x55\x53\x45\x52\x0D\x0A

关于如何正确格式化的任何想法?

【问题讨论】:

  • 您几乎可以肯定应该使用bytes... 不?

标签: python tcp hex


【解决方案1】:

所以,这有点迂回,但使用bytes 对象:

>>> STRINGLENGTH = bytes([11]).decode()
>>> endCommand = '\x00\x00\x00'+STRINGLENGTH+'\x02'
>>> endCommand
'\x00\x00\x00\x0b\x02'

几乎可以肯定,您会想要将str 对象改回bytes 对象,但以上内容应该可以帮助您进行。

我怀疑你在使用hex 函数:

>>> STRINGLENGTH = hex(11)
>>> endCommand = '\x00\x00\x00'+STRINGLENGTH+'\x02'
>>> endCommand
'\x00\x00\x000xb\x02'

您需要了解的基本内容是,您使用的不是“十六进制”,而是字节。十六进制就是字节的传统表示方式。 hex 帮助函数返回一个十六进制表示,作为一个整数的字符串。但这不是你想要的。你想要 对应于值 11 的字节

注意,对于 ascii 范围,chr(i) 可能也可以,所以

>>> STRINGLENGTH = chr(11)
>>> endCommand = '\x00\x00\x00'+STRINGLENGTH+'\x02'
>>> endCommand
'\x00\x00\x00\x0b\x02'

但要小心,假设你想要数字 129,你必须关心编码...

>>> chr(129)
'\x81'

但以字节为单位,在 UTF-8 中,它实际上由两个不同的字节表示

>>> chr(129).encode()
b'\xc2\x81'
>>> list(chr(129).encode())
[194, 129]

这当然取决于编码:

>>> chr(129).encode('latin')
b'\x81'
>>> list(chr(129).encode('latin'))
[129]
>>>

出于这个原因,我认为坚持使用稍微冗长的词更安全:

>>> bytes([129])
b'\x81'

【讨论】:

  • 是的,我正在处理字节。这件设备要到明天晚些时候才能再次提供给我,所以我会试试这个。我尝试了一些非常相似的方法,但是省略了 11 周围的括号,这不起作用(希望只是因为缺少括号)。我也试过 hex() 和 format(STRINGLENGTH, 'x') 都产生了同样的问题。
  • bytes(11) 初始化 length 11 的字节对象,初始化为空字节。构造函数的不同形式见help(bytes)
  • ascii chr() 方法对我有用。我严格使用 ascii 工作,没有用户输入。所以我的输入是相当受控的(一个数字和一个预定义的命令)。非常感谢您的帮助。
猜你喜欢
  • 2012-08-01
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 2010-12-09
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多