次に unpack() 関数の解説をします。
今回はバイナリエディタで見たときに以下のようなデータとなっているファイル(test.dat)の内容を取り込むサンプルを記述します。
01 02 03 04
こちらのファイルから1バイト読み込む場合はこのように書きます。
from struct import * f = open('test.dat', 'rb') print unpack('B', f.read(1)) f.close()
(1,)
この書き方だとタプルで返されるので実際のプログラムでは [0] を加えこのように書きます。
from struct import * f = open('test.dat', 'rb') print unpack('B', f.read(1))[0] f.close()
1
同様に2バイトの場合をはこのようになります。
from struct import * f = open('test.dat', 'rb') print unpack('<H', f.read(2))[0] f.close()
513
2バイト読み込むので read() の引数は2に変わります。
unpack()の説明でも出てきたように2バイト以上の場合はエンディアンの指定が必要となります。
今回もリトルエンディアンで処理しますので < を使います。
10進数だと分かりづらいと思うので16進数で表示するように書き換えます。
from struct import * f = open('test.dat', 'rb') print '0x%X' % unpack('<H', f.read(2))[0] f.close()
0x201
このようにリトルエンディアンなので「0x0201」という並びのデータになります。
同様に4バイトの場合は <L と記述します。
from struct import * f = open('test.dat', 'rb') print '0x%X' % unpack('<L', f.read(4))[0] f.close()
0x4030201
リトルエンディアンの場合、バイナリエディタでの表示とプログラム内での表示は以下の対応となります。
この点は慣れるまで注意が必要です。
バイナリエディタ | プログラム |
---|---|
01 | 0x01 |
01 02 | 0x0201 |
01 02 03 04 | 0x04030201 |