首页 > 编程语言 >python 解析文件【案例3】

python 解析文件【案例3】

时间:2023-02-23 00:22:30浏览次数:39  
标签:struct python print 案例 ctypes test ubyte 解析

使用python进行二进制数据处理的方法。

方法一:使用struct模块,特点轻量化,简单易用。缺点就是可读性不是太好,使用小数据临时使用一下,对于大量的数据解析,写起来比较繁琐,显得有点力不从心。

 

import struct

data = b'\x92\xaa\xbb\xcc\x11\x22\x33\x44'
a,b,c,d,e = struct.unpack(">BBBBI", data)
print("a=0x%x b=0x%x c=0x%x d=0x%x e=0x%x"%(a,b,c,d,e))
packData = struct.pack(">BBBBI", a, b, c, d, e)
print("packData: %s"%packData)

上面的程序会按照给定的格式一次解析数据,得到的输出结果如下:

注:建议采用python3运行,python2不区分bytes和string类型,通过struct.pack()得到的结果为字符串类型,会打印出乱码。

a=0x92 b=0xaa c=0xbb d=0xcc e=0x11223344
packData: b'\x92\xaa\xbb\xcc\x11"3D'

可以看出,能够正确的解析和组装出需要的的数据。

 

struct常用函数原型如下:

struct的方法说明
pack(fmt, v1, v2…) 按照fmt指定的格式化要求,格式化v1,v2等后续参数,返回bytes类型
unpack(fmt, BytesData) 按照fmt指定的格式要求,解析出bytesData里面的数据内容,返回的是数据元组
pack_from(fmt, BytesData, offset) 按照fmt指定的格式要求,解析后面的内容,从offset处开始解析,返回的是数据元组

这个里面的fmt表示格式化字符串,由两个部分组成,第一部分为指定大小端格式,第二部分是依次解析的格式。

大小端格式字符说明 
> 大端模式 和阅读顺序一致,高字节在前(内存地址小),低字节在后(地址大)。
< 小端模式 和大端相反,高字节在后(内存地址大),低字节在前面(地址小)。
@或者= 主机默认字节序 和主机系统强相关,X86/X64默认为小段模式。其中@还会强制4字节对齐。

解析格式如下:

格式字符ctypes类型字节数
c c_char 1
b c_byte 1
B c_ubyte 1
h c_short 2
H c_ushort 2
i c_int 4
I c_uint 4
q c_longlong 8
Q c_ulonglong 8
f c_float 4
d c_double 8
p c_char_p 4(64位系统为8)
P c_void_p 4(64位系统为8)
x c_ubyte(占位padding字节) 1

方法二:使用ctypes模块高效的解析组装二进制数据,这种方法和C比较类似,也更为强大。

import ctypes

class TestBig_Struct(ctypes.BigEndianStructure):
    _fields_=[
        ('b1', ctypes.c_ubyte,1),
        ('b2', ctypes.c_ubyte,1),
        ('b3', ctypes.c_ubyte,1),
        ('b4', ctypes.c_ubyte,1),
        ('lev',ctypes.c_ubyte,4),
        ('BB', ctypes.c_ubyte),
        ('BC', ctypes.c_ubyte),
        ('BD', ctypes.c_ubyte),
        ('SS', ctypes.c_ushort),
    ]
    

class Test_Struct(ctypes.Structure):
    _fields_=[
        ('b1', ctypes.c_ubyte, 1),
        ('b2', ctypes.c_ubyte, 1),
        ('b3', ctypes.c_ubyte, 1),
        ('b4', ctypes.c_ubyte, 1),
        ('lev',ctypes.c_ubyte, 4),
        ('BB', ctypes.c_ubyte),
        ('BC', ctypes.c_ubyte),
        ('BD', ctypes.c_ubyte),
        ('SS', ctypes.c_ushort),
    ]

if __name__ == '__main__':
    test = Test_Struct();
    test.b1 = 1;
    test.b2 = 0;
    test.b3 = 0;
    test.b4 = 1;
    test.lev = 2;
    test.BB = 0xAA;
    test.BC = 0xBB;
    test.BD = 0xCC;
    test.SS = 0xEEFF;
    print ("defEndian", ctypes.string_at(ctypes.addressof(test), ctypes.sizeof(test)))
    test = TestBig_Struct();
    test.b1 = 1;
    test.b2 = 0;
    test.b3 = 0;
    test.b4 = 1;
    test.lev = 2;
    test.BB = 0xAA;
    test.BC = 0xBB;
    test.BD = 0xCC;
    test.SS = 0xEEFF;
    print ("BigEndian", ctypes.string_at(ctypes.addressof(test), ctypes.sizeof(test)))
    ctypes.memmove(ctypes.addressof(test), b'\x92\xaa\xbb\xcc\xee\xff', ctypes.sizeof(test));
    print ("b1:%x"%test.b1)
    print ("b2:%x"%test.b2)
    print ("b3:%x"%test.b3)
    print ("b4:%x"%test.b4)
    print ("lev:%x"%test.lev)
    print ("BB:%x"%test.BB)
    print ("BC:%x"%test.BC)
    print ("BD:%x"%test.BD)
    print ("SS:%x"%test.SS)
    with open("out.bin", "wb") as f:
        f.write(ctypes.string_at(ctypes.addressof(test), ctypes.sizeof(test)));

 

从上面的实例,可以看出来,这个就是采用类似与C结构体的方式,直接解析映射来解析和组装数据。十分的强大。这个实例程序的运行结果如下。

defEndian b')\xaa\xbb\xcc\xff\xee'
BigEndian b'\x92\xaa\xbb\xcc\xee\xff'
b1:1
b2:0
b3:0
b4:1
lev:2
BB:aa
BC:bb
BD:cc
SS:eeff

其中out.bin文件中保存的数据,以十六进制查看如下:

92 aa bb cc ee ff

 

标签:struct,python,print,案例,ctypes,test,ubyte,解析
From: https://www.cnblogs.com/oceaning/p/17146501.html

相关文章

  • 6.mysql优化案例
    1.单表优化;   进行优化:删除原来的三个字段的索引,创建二个字段的索引;    2.两表关联:左连接,在右表创建索引 右连接,在左表创建......
  • Python_Selenium报错:AttributeError: 'WebDriver' object has no attribute 'find_ele
    写法:self.driver.find_element_by_name("wd"),会报错_AttributeError:'WebDriver'objecthasnoattribute'find_element_by_name'  查了下资料原因:`find_element......
  • python 日志解析【案例2】
     要做的事:  1:获取日志内标红的数据(ipython模式正则捕获如下图)         2:转换相关选项的md5和反编码值  3:根据dm值和上个小时的年月日(......
  • Python 解析log日志【案例1】
    sudoaptinstallpython3.8#安装python3python3.8-mpipinstallpython-dateutil#安装dateutil包[2021-09-0311:03:11]**************************E......
  • 【Spring AOP】【九】Spring AOP源码解析-拦截器/通知器链的执行过程
    1 前言上一节我们说了通知器链的而顺序问题,那么这节我们该看看它的执行了。我们拿JDK代理的执行过程来看哈。2 源码分析2.1 方法通读对于JDK动态代理的,那我们再......
  • C#后缀表达式解析计算字符串公式
    当我们拿到一个字符串比如:20+31*(100+1)的时候用口算就能算出结果为3151,因为这是中缀表达式对于人类的思维很简单,但是对于计算机就比较复杂了。相对的后缀表达式适合计算机......
  • 自学python-安装python/pycharm-day03
    安装解释器/学习工具pycharm1.Python简介诞生python的创始人为吉多·范罗苏姆(GuidovanRossum),一般称龟叔。1989年的圣诞节期间,龟叔为了在阿姆斯特丹打发时间,决心......
  • 自学python-计算机基础原理-day02
    python学习第一课什么是python?python是一门编程语言什么是编程语言呢就是人与电脑交互的语言我们用python编写自己想要得软件而python把我们写的语言转化成计算机看......
  • python+playwright 学习-9.页面对象模型Page Object Models
    前言POM(PageObjectModels)页面对象模型已经成了写web自动化的一个标准模型。页面对象模型PageObjectModels页面对象代表Web应用程序的一部分。电子商务Web......
  • 自学python-学习路线-day01
    python自学线路图1.python基础语言1.1变量1.2运算符1.3判断语句if1.4循环语句whliefor1.5函数1.6面向对象2.多线程2.1异常处理2.2文件i/o3.数据结......