加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 解压缩以ASCIIZ字符串结尾的结构

发布时间:2020-12-16 23:40:53 所属栏目:Python 来源:网络整理
导读:我试图使用struct.unpack()来拆分以ASCII字符串结尾的数据记录. 记录(恰好是TomTom ov2记录)具有这种格式(存储的小端): 1个字节 4字节int表示总记录大小(包括此字段) 4字节int 4字节int 可变长度字符串,以null结尾 unpack()要求字符串的长度包含在传递它的
我试图使用struct.unpack()来拆分以ASCII字符串结尾的数据记录.

记录(恰好是TomTom ov2记录)具有这种格式(存储的小端):

> 1个字节
> 4字节int表示总记录大小(包括此字段)
> 4字节int
> 4字节int
>可变长度字符串,以null结尾

unpack()要求字符串的长度包含在传递它的格式中.我可以使用第二个字段和记录其余部分的已知大小–13个字节 – 来获取字符串长度:

str_len = struct.unpack("<xi",record[:5])[0] - 13
fmt = "<biii{0}s".format(str_len)

然后继续完全解包,但由于字符串是空终止的,我真的希望unpack()会为我做.如果我遇到一个不包含自己大小的结构,那么这也很好.

我怎么能做到这一点?

解决方法

我制作了两个新功能,可用作标准包和解包功能的直接替换.它们都支持’z’字符来打包/解包ASCIIZ字符串.格式字符串中’z’字符的出现位置或出现次数没有限制:
import struct

def unpack (format,buffer) :
    while True :
        pos = format.find ('z')
        if pos < 0 :
            break
        asciiz_start = struct.calcsize (format[:pos])
        asciiz_len = buffer[asciiz_start:].find('')
        format = '%s%dsx%s' % (format[:pos],asciiz_len,format[pos+1:])
    return struct.unpack (format,buffer)

def pack (format,*args) :
    new_format = ''
    arg_number = 0
    for c in format :
        if c == 'z' :
            new_format += '%ds' % (len(args[arg_number])+1)
            arg_number += 1
        else :
            new_format += c
            if c in 'cbB?hHiIlLqQfdspP' :
                arg_number += 1
    return struct.pack (new_format,*args)

以下是如何使用它们的示例:

>>> from struct_z import pack,unpack
>>> line = pack ('<izizi',1,'Hello',2,' world!',3)
>>> print line.encode('hex')
0100000048656c6c6f000200000020776f726c64210003000000
>>> print unpack ('<izizi',line)
(1,3)
>>>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读