二进制结构体解析库 namedstruct

码农软件 · 软件分类 · 常用工具包 · 2019-08-14 06:14:07

软件介绍

namedstruct 是一个解析二进制结构体的专用库,它不仅可以解析简单的 C 结构体,还可以支持变长结构体、可扩展的结构体之类复杂的情况。它被用来在 VLCP 中解析 OpenFlow(SDN 专用的二进制协议)。

使用这个库,你会发现,即便是像 OpenFlow 这样复杂的协议,实际上只需要将对应的 C 程序的头文件(比如openflow.h)按照相应的规则进行修改,添加一些简单的参数说明结构体之间的关系,就可以用一行代码将它完整解析出来,或者用一行代码生成出相应的结构体。

可以使用pip安装:

pip install nstruct

示例

###### BASIC STRUCT #####

from namedstruct import *
mytype = nstruct((uint16, 'myshort'),  # unsigned short int
                (uint8, 'mybyte'),       # unsigned char
                (uint8,),               # a padding byte of unsigned char
                (char[5], 'mystr'),   # a 16-byte bytes string
                (uint8,),
                (uint16[5], 'myarray'),    # 
                name = 'mytype',
                padding = 1)
# Create an object
obj0 = mytype()
# Access a field
s = obj0.myshort
obj0.myshort = 12
# Create an object with the specified fields initialized
obj1 = mytype(myshort = 2, mystr = b'123', myarray = [1,2,3,4,5]) 
# Unpack an object from stream, return the object and bytes size used
obj2,size = mytype.parse(b'\x00\x02\x01\x00123\x00\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05')
# Unpack an object from packed bytes
obj3 = mytype.create(b'\x00\x02\x01\x00123\x00\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05')
# Estimate the struct size
size = len(obj0)
# Estimate the struct size excludes automatic padding bytes
size2 = obj0._realsize()
# Pack the object
b = obj0._tobytes()
b2 = mytype.tobytes(obj0)

# Use the type in other structs

mytype2 = nstruct((mytype, 'mydata'),
                (mytype[4], 'mystructarray'),
                name = 'mytype2',
                padding = 1)

obj4 = mytype2()
obj4.mydata.myshort = 12
obj4.mystructarray[0].mybyte = 7
b3 = obj4._tobytes()

###### VARIABLE LENGTH TYPES #####

my_unsize_struct = nstruct((uint16, 'length'),
                        (raw, 'data'),
                        padding = 1,
                        name = 'my_unsize_struct')

"""
>>> my_unsize_struct.create(b'\x00\x07abcde').data
b'abcde'
>>> my_unsize_struct.parse(b'\x00\x07abcde')[0].data
b''
"""

my_size_struct = nstruct((uint16, 'length'),
                        (raw, 'data'),
                        padding = 1,
                        name = 'my_size_struct',
                        prepack = packrealsize('length'),
                        size = lambda x: x.length)
"""
packrealsize('length') is equivalent to:

    def _packsize(x):
        x.length = x._realsize()
"""

"""
>>> my_unsize_struct(data = b'abcde')._tobytes()
b'\x00\x07abcde'
>>> my_unsize_struct.parse(b'\x00\x07abcde')[0].data
b'abcde'
"""

##### EXTENDING #####

my_base = nstruct((uint16, 'length'),
                 (uint8, 'type'),
                 (uint8, 'basedata'),
                 name = 'my_base',
                 size = lambda x: x.length,
                 prepack = packrealsize('length'),
                 padding = 4)

my_child1 = nstruct((uint16, 'data1'),
                    (uint8, 'data2'),
                    name = 'my_child1',
                    base = my_base,
                    criteria = lambda x: x.type == 1,
                    init = packvalue(1, 'type'))

my_child2 = nstruct((uint32, 'data3'),
                   name = 'my_child2',
                   base = my_base,
                   criteria = lambda x: x.type == 2,
                   init = packvalue(2, 'type'))

"""
Fields and most base class options are inherited, e.g. size, prepack, padding
>>> my_child1(basedata = 1, data1 = 2, data2 = 3)._tobytes()
b'\x00\x07\x01\x01\x00\x02\x03\x00'
>>> my_child2(basedata = 1, data3 = 4)._tobytes()
b'\x00\x08\x02\x01\x00\x00\x00\x04'
"""

# Fields in child classes are automatically parsed when the type is determined
obj1, _ = my_base.parse(b'\x00\x07\x01\x01\x00\x02\x03\x00')
"""
>>> obj1.basedata
1
>>> obj1.data1
2
>>> obj1.data2
3
>>> obj1._gettype()
my_child1
"""

# Base type can be used in fields or arrays of other structs

my_base_array = nstruct((uint16, 'total_len'),
                       (my_base[0], 'array'),
                       name = 'my_base_array',
                       padding = 1,
                       size = lambda x: x.total_len,
                       prepack = packrealsize('total_len'))

obj2 = my_base_array()
obj2.array.append(my_child1(data1 = 1, data2 = 2, basedata = 3))
obj2.array.append(my_child2(data3 = 4, basedata = 5))
"""
>>> obj2._tobytes()
b'\x00\x12\x00\x07\x01\x03\x00\x01\x02\x00\x00\x08\x02\x05\x00\x00\x00\x04'
"""
obj3, _ = my_base_array.parse(b'\x00\x12\x00\x07\x01\x03\x00\x01\x02\x00\x00\x08\x02\x05\x00\x00\x00\x04')
"""
>>> obj3.array[0].data2
2
"""

 

本文地址:https://codercto.com/soft/d/12317.html

Algorithms for Image Processing and Computer Vision

Algorithms for Image Processing and Computer Vision

Parker, J. R. / 2010-12 / 687.00元

A cookbook of algorithms for common image processing applications Thanks to advances in computer hardware and software, algorithms have been developed that support sophisticated image processing with......一起来看看 《Algorithms for Image Processing and Computer Vision》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具