提问人:Sir D 提问时间:2/7/2012 最后编辑:Peter MortensenSir D 更新时间:6/19/2017 访问量:4217
在 Python 中解压缩格式字符
Unpack format characters in Python
问:
我需要这个Perl字符串的Python模拟:
unpack("nNccH*", string_val)
我需要 Python 格式字符的 - 数据格式。nNccH*
在Perl中,它将二进制数据解压缩为五个变量:
- “network”(big-endian)中的 16 位值
- “network”(big-endian)中的 32 位值
- 有符号字符(8 位整数)值
- 有符号字符(8 位整数)值
- 十六进制字符串,高半字节优先
但是我不能在Python中做到这一点
更多:
bstring = ''
while DataByte = client[0].recv(1):
bstring += DataByte
print len(bstring)
if len(bstring):
a, b, c, d, e = unpack("nNccH*", bstring)
我从来没有用Perl或Python写过,但我目前的任务是写一个用Perl写的多线程Python服务器......
答:
7赞
Eli Bendersky
2/7/2012
#1
您要查找的等效 Python 函数是 。格式字符串的文档如下:http://docs.python.org/library/struct.htmlstruct.unpack
如果您真正解释您需要什么样的开箱,您将有更好的机会获得帮助。不是每个人都知道Perl。
评论
0赞
Sir D
2/7/2012
谢谢。我已经阅读了 perl 和 python 解包文档。但到目前为止,我不明白有些时刻。
0赞
Senthil Kumaran
2/7/2012
@Eli - 直接翻译可能会有小麻烦。例如,如何在 python 中执行 H*?我想,用户本可以更好地表达这个问题。
0赞
Eli Bendersky
2/7/2012
@SenthilKumaran:请注意,用户在我回答后编辑了问题。在编辑之前,他没有在Perl中列出格式chars的含义
0赞
S.Lott
2/7/2012
@SirD:“到目前为止,我不明白有些时刻”。请具体说明您不理解的内容。请更新问题,说出您不理解的内容。
8赞
unutbu
2/7/2012
#2
Perl格式相当于Python格式。
在 Python 中没有 Perl 的直接等价物。"nNcc"
"!HLbb"
"H*"
有两个问题。
- Python 不接受通配符,
struct.unpack
*
- Python 不会“十六进制化”数据字符串
struct.unpack
第一个问题可以使用类似 的辅助函数来解决。unpack
第二个问题可以通过以下方法解决:binascii.hexlify
import struct
import binascii
def unpack(fmt, data):
"""
Return struct.unpack(fmt, data) with the optional single * in fmt replaced with
the appropriate number, given the length of data.
"""
# http://stackoverflow.com/a/7867892/190597
try:
return struct.unpack(fmt, data)
except struct.error:
flen = struct.calcsize(fmt.replace('*', ''))
alen = len(data)
idx = fmt.find('*')
before_char = fmt[idx-1]
n = (alen-flen)//struct.calcsize(before_char)+1
fmt = ''.join((fmt[:idx-1], str(n), before_char, fmt[idx+1:]))
return struct.unpack(fmt, data)
data = open('data').read()
x = list(unpack("!HLbbs*", data))
# x[-1].encode('hex') works in Python 2, but not in Python 3
x[-1] = binascii.hexlify(x[-1])
print(x)
当在此 Perl 脚本生成的数据上进行测试时:
$line = pack("nNccH*", 1, 2, 10, 4, '1fba');
print "$line";
Python 脚本产生
[1, 2, 10, 4, '1fba']
评论
0赞
Sven Marnach
2/7/2012
另一种选择是 。binascii.hexlify()
str.encode("hex")
1赞
Mark Tolonen
2/7/2012
如果您想要 Python 3 兼容性,则需要在计算时,否则会产生“16.0”并破坏格式字符串。//
n
str(n)
评论
"while DataByte = client[0].recv(1):"
不是 Python。这永远行不通。*
H*