【问题标题】:Unpack format characters in Python在 Python 中解压缩格式字符
【发布时间】:2012-02-28 21:16:53
【问题描述】:

我需要这个 Perl 字符串的 Python 模拟:

unpack("nNccH*", string_val)

我需要nNccH* - Python 格式字符的数据格式。

在 Perl 中,它将二进制数据解压缩为五个变量:

  • “网络”中的 16 位值(大端)
  • “网络”中的 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 服务器...

【问题讨论】:

  • 我可以找到除 H* 之外的所有内容的等价物,我假设您会使用 p 或 s。
  • 您需要计算字符串大小,这个答案可能会有所帮助。 stackoverflow.com/a/5849224/70350
  • "while DataByte = client[0].recv(1):" 不是 Python。这永远行不通。
  • @SenthilKumaran: AFAIR * 的意思是“尽可能多的元素”,所以他可以解压H* 之前的所有内容,然后直接抓取其余部分而不需要解压
  • 顺便说一句,D 先生,感谢您编辑和澄清问题。 S.Lott 注意到,最后一个代码 sn-p 没有什么意义

标签: python perl unpack


【解决方案1】:

Perl 格式 "nNcc" 等效于 Python 格式 "!HLbb"。 Perl 的"H*" 在 Python 中没有直接的等价物。

有两个问题。

  • Python 的struct.unpack 不接受通配符*
  • Python 的 struct.unpack 不会“hexlify”数据字符串

第一个问题可以使用像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']

【讨论】:

  • binascii.hexlify() 的替代品是str.encode("hex")
  • 如果你想要 Python 3 的兼容性,在计算 n 时需要 //,否则 str(n) 会生成 '16.0' 并破坏格式字符串。
  • 在 Python 3.4 和更新版本中,有struct.iter_unpackHere 是一个演示。
【解决方案2】:

您正在寻找的等效 Python 函数是 struct.unpack。格式字符串的文档在这里:http://docs.python.org/library/struct.html

如果你真正解释你需要什么样的拆包,你将有更好的机会获得帮助。不是每个人都知道 Perl。

【讨论】:

  • 谢谢。我已经阅读了 perl 和 python unpack 文档。但到目前为止,我有些时候不明白。
  • @Eli - 直接翻译可能会有小问题。例如,如何在 python 中做 H*?我想,用户本可以更好地表达这个问题。
  • @SenthilKumaran:请注意,用户在我的回答之后 编辑了问题。在编辑之前,他没有列出 Perl 中格式字符的含义
  • @SirD:“到目前为止,我有些不明白”。请具体说明您不了解的内容。请更新问题,说出你不明白的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多