在 Python 中解压格式字符 [英] Unpack format characters in Python

查看:47
本文介绍了在 Python 中解压格式字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need the Python analog for this Perl string:

unpack("nNccH*", string_val)

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

I need the nNccH* - data format in Python format characters.

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

In Perl it unpack binary data to five variables:

  • 网络"中的 16 位值(大端)
  • 网络"中的 32 位值(大端)
  • 有符号字符(8 位整数)值
  • 有符号字符(8 位整数)值
  • 十六进制字符串,高位先行

但是我不能在 Python 中做到这一点

But I can't do it in 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 服务器...

I never wrote in Perl or Python, but my current task is to write a multithreading Python server that was written in Perl...

推荐答案

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

The Perl format "nNcc" is equivalent to the Python format "!HLbb". There is no direct equivalent in Python for Perl's "H*".

有两个问题.

  • Python 的struct.unpack 不接受通配符,*
  • Python 的 struct.unpack 不会十六进制化"数据字符串
  • Python's struct.unpack does not accept the wildcard character, *
  • Python's struct.unpack does not "hexlify" data strings

第一个问题可以使用像 unpack 这样的辅助函数来解决.

The first problem can be worked-around using a helper function like unpack.

第二个问题可以用binascii.hexlify解决:

The second problem can be solved using 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 脚本生成的数据进行测试时:

When tested on data produced by this Perl script:

$line = pack("nNccH*", 1, 2, 10, 4, '1fba');
print "$line";

Python 脚本生成

The Python script yields

[1, 2, 10, 4, '1fba']

这篇关于在 Python 中解压格式字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆