まずはバイナリエディタなどで以下のサンプルバイナリデータを作ろう。
hoge.bin
FF AA AA 41 41 41 E3 81 82 E3 81 82 E3 81 82
上のバイナリデータを以下のように定義してみた。
初めの1byte: 0xFF = signed char (1) = 255
次の2bytes: 0xAAAA = unsigned short (2) = 43690
次の3bytes: 0x414141 = char[] = 'AAA'
次の9bytes: 0xE38182E38182E38182 = char[] = u'あああ'
早速このファイルをpythonで読み込み解析してみよう。
bin_read.py
# -*- coding: utf-8 -*-
import struct
print u"先ずは先頭から順番に読み込む"
f = open('hoge.bin', 'rb')
print '1. signed char (1): %s' % struct.unpack('<b', f.read(1))
print '2. unsigned short (2): %s' % struct.unpack('H', f.read(2))
print '3. char[3]: %s' % struct.unpack('3s', f.read(3))
print '4. char[9]: %s' % struct.unpack('9s', f.read(9))
f.close()
print u"tupleへ一気に格納することも可"
f = open('hoge.bin', 'rb')
data1, data2, data3, data4 = struct.unpack('<bH3s9s', f.read())
print '1. signed char (1): %s' % data1
print '2. unsigned short (2): %s' % data2
print '3. char[3]: %s' % data3
print '4. char[9]: %s' % data4
f.close()
以下が実行結果。
一部表示が文字化けしているが("縺ゅ≠縺")、これはUTF-8の "あああ" である。
C:\>bin_read.py
先ずは先頭から順番に読み込む
1. signed char (1): -1
2. unsigned short (2): 43690
3. char[3]: AAA
4. char[9]: 縺ゅ≠縺
tupleへ一気に格納することも可
1. signed char (1): -1
2. unsigned short (2): 43690
3. char[3]: AAA
4. char[9]: 縺ゅ≠縺
バイナリデータを読み込む上での重要箇所は、struct.unpack(arg1, arg2) の部分だ。arg1にはフォーマット形式、arg2には解析対象のバイナリデータをそれぞれ代入する。
上の例のフォーマット形式 '<bH3s9s' を丁寧に説明すると、まず最初の1文字目はバイトオーダーで "<" はリトルインディアンなデータを表す。
その次の "b" は signed char (1)を、
次の "H" は unsigned short(2)を、
次の "3s" は 文字列(char[]) 3バイトを、
次の "9s" で 文字列(char[]) 9バイトをそれぞれ表している。
フォーマット形式の詳細は本家サイトのstructの解説をご参照あれ。
今回はこちらも参考にさせてもらった。