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

前端之家收集整理的这篇文章主要介绍了python – 解压缩以ASCIIZ字符串结尾的结构前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图使用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('\0')
        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)
>>>
原文链接:https://www.f2er.com/python/186762.html

猜你在找的Python相关文章