字符串到 python 中的 wstring
string to wstring in python
我有一个 udp 套接字,它接收不同长度的数据报。
数据报的第一个指定它将接收什么类型的数据,例如 64-means bool false,65-means bool true,66-means sint,67-means int 等等。由于大多数数据类型都知道长度,但是当涉及到字符串和 wstring 时,第一个字节表示 85 表示字符串,接下来的 2 个字节表示字符串长度,然后是实际字符串。对于 wstring 85,接下来的 2 个字节表示 wstring 长度,然后是实际 wstring。
为了解析上面那种 wstring 格式 b'U\x00\x07\x00C\x00o\x00u\x00p\x00o\x00n\x001'
我使用了下面的代码
data = str(rawdata[3:]).split("\x00")
data = "".join(data[1:])
data = "".join(data[:-1])
这是正确的还是其他简单的方法?
当我收到数据报时,我也需要发送数据报。但是我不知道如何创建数据报,因为 socket.sendto 需要 bytes
。如果我尝试将字符串转换为 utf-16
格式,它将转换为 wstring。如果是这样,我将如何将其余信息添加到 bytes
从上面的数据报信息来看U
-85是wstring,\x00\x07
-7长度的wstring数据,\x00C\x00o\x00u\x00p\x00o\x00n\x001
-是实际的字符串Coupon1
完整的答案取决于您打算如何处理结果数据。用 '\x00'
拆分字符串(假设这就是你的意思?不确定我是否理解为什么那里有两个反斜杠)并没有真正意义。首先使用 wstring
类型的原因是能够表示不是普通旧 8 位(实际上是 7 位)ascii 的字符。如果您有任何不是标准罗马字符的字符,它们很可能有除零字节以外的字符分隔字符,在这种情况下,您的 split
结果将毫无意义。
警告:由于您提到 sendto
需要字节,我假设您使用的是 python3。 python2.
下的细节会略有不同
无论如何,如果我明白您的意思,"utf-16-be" 编解码器可能就是您要找的。 ("utf-16" 编解码器将 "byte order marker" 放在您可能不想要的编码字符串的开头;"utf-16-be" 只是将大端 16 位字符放入字节字符串。 ) 解码可以像这样执行:
rawdata = b'U\x00\x07\x00C\x00o\x00u\x00p\x00o\x00n\x001'
dtype = rawdata[0]
if dtype == 85: # wstring
dlen = ord(rawdata[1:3].decode('utf-16-be'))
data = rawdata[3: (dlen * 2) + 3]
dstring = data.decode('utf-16-be')
这会将 dstring
保留为 python unicode 字符串。在 python3 中,所有字符串都是 unicode。大功告成。
可以这样编码:
tosend = 'Coupon1'
snd_data = bytearray([85]) # wstring indicator
snd_data += bytearray([(len(tosend) >> 8), (len(tosend) & 0xff)])
snd_data += tosend.encode('utf-16-be')
我有一个 udp 套接字,它接收不同长度的数据报。 数据报的第一个指定它将接收什么类型的数据,例如 64-means bool false,65-means bool true,66-means sint,67-means int 等等。由于大多数数据类型都知道长度,但是当涉及到字符串和 wstring 时,第一个字节表示 85 表示字符串,接下来的 2 个字节表示字符串长度,然后是实际字符串。对于 wstring 85,接下来的 2 个字节表示 wstring 长度,然后是实际 wstring。
为了解析上面那种 wstring 格式 b'U\x00\x07\x00C\x00o\x00u\x00p\x00o\x00n\x001'
我使用了下面的代码
data = str(rawdata[3:]).split("\x00")
data = "".join(data[1:])
data = "".join(data[:-1])
这是正确的还是其他简单的方法?
当我收到数据报时,我也需要发送数据报。但是我不知道如何创建数据报,因为 socket.sendto 需要 bytes
。如果我尝试将字符串转换为 utf-16
格式,它将转换为 wstring。如果是这样,我将如何将其余信息添加到 bytes
从上面的数据报信息来看U
-85是wstring,\x00\x07
-7长度的wstring数据,\x00C\x00o\x00u\x00p\x00o\x00n\x001
-是实际的字符串Coupon1
完整的答案取决于您打算如何处理结果数据。用 '\x00'
拆分字符串(假设这就是你的意思?不确定我是否理解为什么那里有两个反斜杠)并没有真正意义。首先使用 wstring
类型的原因是能够表示不是普通旧 8 位(实际上是 7 位)ascii 的字符。如果您有任何不是标准罗马字符的字符,它们很可能有除零字节以外的字符分隔字符,在这种情况下,您的 split
结果将毫无意义。
警告:由于您提到 sendto
需要字节,我假设您使用的是 python3。 python2.
无论如何,如果我明白您的意思,"utf-16-be" 编解码器可能就是您要找的。 ("utf-16" 编解码器将 "byte order marker" 放在您可能不想要的编码字符串的开头;"utf-16-be" 只是将大端 16 位字符放入字节字符串。 ) 解码可以像这样执行:
rawdata = b'U\x00\x07\x00C\x00o\x00u\x00p\x00o\x00n\x001'
dtype = rawdata[0]
if dtype == 85: # wstring
dlen = ord(rawdata[1:3].decode('utf-16-be'))
data = rawdata[3: (dlen * 2) + 3]
dstring = data.decode('utf-16-be')
这会将 dstring
保留为 python unicode 字符串。在 python3 中,所有字符串都是 unicode。大功告成。
可以这样编码:
tosend = 'Coupon1'
snd_data = bytearray([85]) # wstring indicator
snd_data += bytearray([(len(tosend) >> 8), (len(tosend) & 0xff)])
snd_data += tosend.encode('utf-16-be')