结构解压缩变量

时间:2018-02-04 09:39:35

标签: python python-3.x struct

我正在尝试将我的代码转换为 Python 3 ,并且在使用问题时遇到了 Struct 的问题。当我在解包时不使用变量时,它会给出我想要的结果,但是当我使用变量时,它并没有给出我需要给出的结果。

我使用名为“ dataReceived ”的def来从socket获取数据。然后我用struct解压缩它。

没有变量的代码(它给出了真实结果)(结果是2)(数据包与我从套接字获得的数据包相同):

user.profile.country

带变量的代码(从def dataReceived获取数据包)(它给出错误结果)(结果为98)(并且两个数据包都相同)

packetFormat = unpack('!b', b'\x02\x01]\x00\x1c\x01\x01\xb0\x00\taMtIyfKal\x00\x07ActiveX\x00\x165.0 (Windows)-Netscape\x00)\xed\x06\x00\x00\x00@3407d2fbeefadbf85fa0f48bbac8337e026e0669b6be226156fd6fb4d575ef16\x00\xd9A=t&SA=t&SV=t&EV=t&MP3=t&AE=t&VE=t&ACC=t&PR=t&SP=f&SB=f&DEB=f&V=WIN 28,0,0,137&M=Adobe Windows&R=1280x1024&COL=color&AR=1.0&OS=Windows 8&ARCH=x86&L=tr&IME=t&PR32=t&PR64=t&PT=ActiveX&AVD=f&LFD=f&WD=f&TLS=t&ML=5.1&DP=72\x00\x00\x00\x00\x00\x00\x02\xca\x00\x00'[:1])[0]
print(packetFormat)

1 个答案:

答案 0 :(得分:2)

在您收到的字节值上调用str并不能达到您的预期效果。

这是旧的,良好的行为:

>>> bs = b'\x02'
>>> struct.unpack('!b', bs)
(2,)

在新代码中,bytes值被强制转换为字符串:

>>> s = str(bs)

然后它解压缩了:

>>> struct.unpack('!b', bytes(s, 'utf-8'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: unpack requires a bytes object of length 1

看起来字符串值有些奇怪:

>>> s
"b'\\x02'"
>>> struct.unpack('!b', bytes(s, 'utf-8')[:1])
(98,)

str值上调用bytes会向我们提供bytes&#39; repr作为字符串;要将bytes作为字符串,我们需要调用bytesdecode方法。请注意,您的数据包数据似乎编码为latin-1,而不是utf-8。这对于第一个字节并不重要,但是如果要解码整个字节串,则会发生这种情况。

>>> s = bs.decode('latin-1')
>>> struct.unpack('!b', bytes(s, 'latin-1'))
(2,)

因此,请不要在您解压缩的str值上调用bytes,或者对其进行解码,或者更好的是,将其保留为bytes并避免不必要的编码和解码。您可以将字节解码为unicode字符串,并将它们存储在您的实例上。

def dataReceived(this, packet):
    this.package = packet.decode('latin-1')  # Store packet data as a unicode string
    packetFormat = unpack('!b', packet[:1])[0]