python模块介绍- struct 二进制数据结构

时间:2022-06-13 20:59:24

出自:http://blog.csdn.net/oychw/article/details/8919519

2013-05-13 磁针石

#承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 博客:http://blog.csdn.net/oychw

#版权所有,转载刊登请来函联系

#深圳测试自动化python项目接单群113938272深圳会计软件测试兼职 6089740

#深圳地摊群 66250781武冈洞口城步新宁乡情群49494279

#自动化测试和python群组:http://groups.google.com/group/automation_testing_python

#参考资料:《The PythonStandard Libraryby Example 2011》

              实现字节数据和python数据类型的转换。格式指示器会有类似于re模块一样的变异机制。所以创建Struct实例,再调用实例方法会比使用模块函数更加有效。

              打包和解包:

文件:struct_pack.py

import binascii

 

values = (1, 'ab', 2.7)

s = struct.Struct('I 2s f')

packed_data = s.pack(*values)

 

print 'Original values:', values

print 'Format string :', s.format

print 'Uses          :', s.size, 'bytes'

print 'Packed Value  :', binascii.hexlify(packed_data)

执行结果:

Original values: (1, 'ab', 2.7)

Format string : I 2s f

Uses          : 12 bytes

Packed Value  : 0100000061620000cdcc2c40

 

文件:struct_unpack.py

import struct

import binascii

 

packed_data =binascii.unhexlify('0100000061620000cdcc2c40')

 

s = struct.Struct('I 2s f')

unpacked_data = s.unpack(packed_data)

print 'Unpacked Values:', unpacked_data

执行结果:

Unpacked Values: (1, 'ab', 2.700000047683716)

字节序:

import struct

import binascii

 

values = (1, 'ab', 2.7)

print 'Original values:', values

 

endianness = [

    ('@', 'native, native'),

    ('=', 'native, standard'),

    ('<', 'little-endian'),

    ('>', 'big-endian'),

    ('!', 'network'),

    ]

 

for code, name in endianness:

    s = struct.Struct(code + ' I2s f')

    packed_data = s.pack(*values)

    print

    print 'Format string  :', s.format, 'for', name

    print 'Uses           :', s.size, 'bytes'

    print 'Packed Value   :', binascii.hexlify(packed_data)

print 'Unpacked Value :',s.unpack(packed_data)

                            执行结果:

Original values: (1, 'ab', 2.7)

Format string  : @ I 2s f fornative, native

Uses           : 12 bytes

Packed Value   :0100000061620000cdcc2c40

Unpacked Value : (1, 'ab', 2.700000047683716)

 

Format string  : = I 2s f fornative, standard

Uses           : 10 bytes

Packed Value   :010000006162cdcc2c40

Unpacked Value : (1, 'ab', 2.700000047683716)

 

Format string  : < I 2s f forlittle-endian

Uses           : 10 bytes

Packed Value   :010000006162cdcc2c40

Unpacked Value : (1, 'ab', 2.700000047683716)

 

Format string  : > I 2s f forbig-endian

Uses           : 10 bytes

Packed Value   :000000016162402ccccd

Unpacked Value : (1, 'ab', 2.700000047683716)

 

Format string  : ! I 2s f fornetwork

Uses           : 10 bytes

Packed Value   :000000016162402ccccd

Unpacked Value : (1, 'ab', 2.700000047683716)

性能要求较高的情况下可以使用buffer,pack_into()和unpack_from()可以直接和buffer交互。

import struct

import binascii

 

s = struct.Struct('I 2s f')

values = (1, 'ab', 2.7)

print 'Original:', values

 

print

print 'ctypes string buffer'

 

import ctypes

b = ctypes.create_string_buffer(s.size)

print 'Before  :',binascii.hexlify(b.raw)

s.pack_into(b, 0, *values)

print 'After   :',binascii.hexlify(b.raw)

print 'Unpacked:', s.unpack_from(b, 0)

 

print

print 'array'

 

import array

a = array.array('c', '\0' * s.size)

print 'Before  :',binascii.hexlify(a)

s.pack_into(a, 0, *values)

print 'After   :',binascii.hexlify(a)

print 'Unpacked:', s.unpack_from(a, 0)

执行结果:

Original: (1, 'ab', 2.7)

 

ctypes string buffer

Before  :000000000000000000000000

After   : 0100000061620000cdcc2c40

Unpacked: (1, 'ab', 2.700000047683716)

 

array

Before  :000000000000000000000000

After   :0100000061620000cdcc2c40

Unpacked: (1, 'ab', 2.700000047683716)

 

Struct模块可以和namedtuple配合,使二进制数据具备更好的可读性:

>>> record = 'raymond   \x32\x12\x08\x01\x08'

>>> name, serialnum, school, gradelevel = unpack('<10sHHb',record)

 

>>> from collections import namedtuple

>>> Student = namedtuple('Student', 'name serialnum schoolgradelevel')

>>> Student._make(unpack('<10sHHb', record))

Student(name='raymond   ',serialnum=4658, school=264, gradelevel=8)

 

类似模块:xdrlibarray