发送数据的正确编码

2024-09-28 21:02:07 发布

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

在Python2中一些琐碎的事情在Python3中变得有点乏味。我发送一个字符串,后跟一些十六进制值:

buffer = "ABCD"
buffer += "\xCA\xFE\xCA\xFE"

发送时会出现错误,我在其他帖子中读到,解决方案是使用sendallencode

s.sendall(buffer.encode("UTF-8"))

但是,在网络中发送十六进制值的是UTF-8编码:

c3 8a c3 be c3 8a c3 be

而不是我定义的确切字节。在不使用外部库的情况下,或者在不必将数据“转换”到另一个结构的情况下,我应该如何做到这一点

我知道这个问题已经被广泛提出,但我找不到令人满意的解决办法


Tags: 字符串buffer情况be事情python3utfencode
2条回答

根据问题中的信息,可能可以将数据编码为拉丁语-1,因为这不会改变任何字节值

buffer = "ABCD"
buffer += "\xCA\xFE\xCA\xFE"

payload = buffer.encode("latin-1")
print(payload)
b'ABCD\xca\xfe\xca\xfe'

另一方面,你可以从拉丁语1中解码:

buffer = payload.decode('latin-1')
buffer
'ABCDÊþÊþ'

但您可能更愿意将消息的文本和二进制部分保留为各自的类型:

encoded_text = payload[:4]
encoded_text
b'ABCD'
text = encoded_text.decode('latin-1')
print(text)
ABCD
binary_data = payload[4:]
binary_data
b'\xca\xfe\xca\xfe'

如果您的文本包含无法编码为拉丁语-1-'你好,世界' 例如,您可以采用相同的方法,但是您需要将文本编码为UTF-8,同时将二进制数据编码为“latin-1”;产生的字节将需要拆分为文本和二进制部分,并分别进行解码

最后:在Python3中,像'\xca\xfe\xca\xfe'这样编码字符串文字是一种糟糕的样式-最好将它们声明为像b'\xca\xfe\xca\xfe'这样的字节文字

您可能认为Python3使事情变得更加困难,但正是相反的意图。您遇到了字符集强制问题。在Python2中,有多种原因会与UTF-8和Unicode字符集混淆。现在已经修好了

首先,如果需要发送二进制数据,最好选择ad-hoc类型,即bytes。使用Python3,在字符串前面加一个b就足够了。这将解决您的问题:

buffer = b"ABCD"
buffer += b"\xCA\xFE\xCA\xFE"
s.sendall(buffer)

当然,bytes对象没有encode方法,因为它已经被编码为二进制。但是它有相反的方法decode

当您使用不带前缀的引号创建str对象时,默认情况下,Python3将使用Unicode编码(这是由Python2中的unicode类型或u前缀强制执行的)。这意味着您需要使用encode方法来获取二进制数据

相反,直接使用bytes来存储二进制数据,因为不会发生编码操作,它将保持您键入的状态

错误can only concatenate str (not "bytes") to str不言而喻。Python抱怨它不能将strbytes连接起来,因为前面的数据需要进一步的步骤,即编码,以使+操作有意义

相关问题 更多 >