5

我需要这个 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 服务器......

4

2 回答 2

8

Perl 格式"nNcc"等同于 Python 格式"!HLbb"。在 Python 中,对于 Perl 的"H*".

有两个问题。

  • Pythonstruct.unpack不接受通配符,*
  • Pythonstruct.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']
于 2012-02-07T13:31:42.230 回答
7

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

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

于 2012-02-07T12:37:42.033 回答