zoukankan      html  css  js  c++  java
  • Pytho, struct处理二进制(pack和unpack)

    [转]Python使用struct处理二进制(pack和unpack用法)

    转载自:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html

    这篇文章写的很好,所以无耻的转了。。

    有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体.

    struct模块中最重要的三个函数是pack(), unpack(), calcsize()

    # 四号程序员 http://www.coder4.com
    1
    2
    3
    4
    5
    6
    7
    8
    #  按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
    pack(fmt, v1, v2, ...)
     
    # 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
    unpack(fmt, string)      
     
    # 计算给定的格式(fmt)占用多少字节的内存
    calcsize(fmt)

    上述fmt中,支持的格式为:

    FORMATC TYPEPYTHON TYPESTANDARD SIZENOTES
    x pad byte no value    
    c char string of length 1 1  
    b signed char integer 1 (3)
    B unsigned char integer 1 (3)
    ? _Bool bool 1 (1)
    h short integer 2 (3)
    H unsigned short integer 2 (3)
    i int integer 4 (3)
    I unsigned int integer 4 (3)
    l long integer 4 (3)
    L unsigned long integer 4 (3)
    q long long integer 8 (2), (3)
    Q unsigned long long integer 8 (2), (3)
    f float float 4 (4)
    d double float 8 (4)
    s char[] string    
    p char[] string    
    P void * integer   (5), (3)

    注1.q和Q只在机器支持64位操作时有意思

    注2.每个格式前可以有一个数字,表示个数

    注3.s格式表示一定长度的字符串,4s表示长度为4的字符串,但是p表示的是pascal字符串

    注4.P用来转换一个指针,其长度和机器字长相关

    注5.最后一个可以用来表示指针类型的,占4个字节

    为了同c中的结构体交换数据,还要考虑有的c或c++编译器使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下:

    CHARACTERBYTE ORDERSIZEALIGNMENT
    @ native native native
    = native standard none
    < little-endian standard none
    > big-endian standard none
    ! network (= big-endian) standard none

     < : Little-Endian就是低位字节排放在内存的低地址端(栈顶),高位字节排放在内存的高地址端(栈底)

    >:Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

    !: 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。

    请编写一个bmpinfo.py,可以检查任意文件是否是位图文件,如果是,打印出图片大小和颜色数# _*_ coding:utf-8_*_

    import base64, struct


    def bmp_info(data):
    t = struct.unpack('<2c6I2H', data[:30]) # 注意因为前面的解析格式只有30位,所以后面的byte串只取前30位,否则会出错;
    '<2c6I2H' == ‘<ccIIIIIIHH’
        if t[0] == b'B' and t[1] == b'M':
    return {
    'width': t[6],
    'height': t[7],
    'color': t[-1]
    }
    else:
    print("%s is not a bmp file" % data)

    # test
    bmp_data = base64.b64decode('Qk1oAgAAAAAAADYAAAAoAAAAHAAAAAoAAAABABAAAAAAADICAAASCwAAEgsAAAAAAAAAAAAA/3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9/AHwAfAB8AHwAfAB8AHwAfP9//3//fwB8AHwAfAB8/3//f/9/AHwAfAB8AHz/f/9//3//f/9//38AfAB8AHwAfAB8AHwAfAB8AHz/f/9//38AfAB8/3//f/9//3//fwB8AHz/f/9//3//f/9//3//f/9/AHwAfP9//3//f/9/AHwAfP9//3//fwB8AHz/f/9//3//f/9/AHwAfP9//3//f/9//3//f/9//38AfAB8AHwAfAB8AHwAfP9//3//f/9/AHwAfP9//3//f/9//38AfAB8/3//f/9//3//f/9//3//fwB8AHwAfAB8AHwAfAB8/3//f/9//38AfAB8/3//f/9//3//fwB8AHz/f/9//3//f/9//3//f/9/AHwAfP9//3//f/9/AHwAfP9//3//fwB8AHz/f/9/AHz/f/9/AHwAfP9//38AfP9//3//f/9/AHwAfAB8AHwAfAB8AHwAfAB8/3//f/9/AHwAfP9//38AfAB8AHwAfAB8AHwAfAB8/3//f/9//38AfAB8AHwAfAB8AHwAfAB8/3//f/9/AHwAfAB8AHz/fwB8AHwAfAB8AHwAfAB8AHz/f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//38AAA==')
    bi = bmp_info(bmp_data)
    assert bi['width'] == 28
    assert bi['height'] == 10
    assert bi['color'] == 16
    print('ok')
  • 相关阅读:
    redis 五种数据结构详解(string,list,set,zset,hash)
    推荐一个同步Mysql数据到Elasticsearch的工具
    一些经验,用来鉴别不太靠谱的公司或工作(面试是双向的,是你最好的了解这个公司的机会)
    OpenSSL 使用 base64 编码/解码(liang19890820)
    Qt之QEvent(所有事件的翻译)
    Go 在 Windows 上用户图形界面 GUI 解决方案 Go-WinGUI 国产(使用cef 内核)
    卷积神经网络CNN
    Event Driven Architecture
    wineshark分析抓取本地回环包
    僵尸进程与孤儿进程
  • 原文地址:https://www.cnblogs.com/xiaohai2003ly/p/8696112.html
Copyright © 2011-2022 走看看