[明治大学総合数理学部 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/meiji_univ) 21日目の記事です. 現象数理学科4年の江口です. 1年ぶりのQiita投稿です. 昨年の初投稿記事「[WaveNetまとめ](https://qiita.com/MasaEguchi/items/cd5f7e9735a120f27e2a)」は拙い文章でしたが, 読んでくださった方ありがとうございます!
今回はバイナリデータをPythonで扱う方法をまとめました.
といってもバイナリデータを読み込んで, 16進数表記で表示する方法だけです.
背景(この記事を書くに至った経緯)
ある地域のある時刻におけるレーダ雨量データを扱う必要がありました. このデータはバイナリで, ヘッダ部分(最初の64byte)に, 本来は16進数で意味を持つ観測地や観測日時, レーダ雨量データのデータサイズの情報があります. 16進数に書き直してデータの詳細を理解する必要があったわけです. そこでいざ調べてみると色々記事あるのですが, まあ難しいわけです(以下を読むと大したことはないのですが, サーチの下手な自分には大変だった). というわけで試行錯誤しながら身につけた方法を自分用にまとめなおしました.
目的
バイナリデータを, データの内容がわかるように書き換える.
そもそもバイナリデータって?
バイナリデータとは「2進数で表されているデータ」のことです。コンピュータは電流のONかOFF, 「0」か「1」でデータを表現します。と思っていたのですが, 2進数に限らずコンピュータが理解できるように書かれているデータ全般を指すらしいです。人間が読んで理解できないデータですね。
これは「テキストデータ」と対比して使われます。テキストデータは.txtなど文字列のデータで, 人間が読めるデータです。
バイナリデータの取り扱い
バイナリデータの読み込み
以下のコードで読み込めます.
with open(file_path, "rb") as f:
buf = f.read(byteSize)
そうです, これだけでバイナリデータを読み込めます. C言語だとbuf=malloc(sizeof(char)*byteSize);
からのfread(buf, sizeof(char), byteSize, fp);
と少し手間がかかりました.
注意点はopen(file_path, "rb")
の部分です. "r"が読み込み, "b"がバイナリデータに対しての操作を意味します(書き込みのときは"w").
buf = f.read(byteSize)
のbyteSizeは読み込むデータのバイト数を指します.
注) buf=f.read(byteSize).hex()
と後ろにhex()を加えると16進数に変換してくれますが, 各桁1つずつが配列に代入されるので, 後の処理で再度配列2つずつに区切るのが面倒になります.
16進数表示
先ほど読み込んだバイナリデータの1番目, buf[0]を16進数でprintするコードは以下の通りです.
print("{0:02x}".format(buf[0]))
python3のprintの書き方は色々ありますが, 今回はformat()を使って変数の値をprintします.
"02x"は値を16進数("x"の部分)で, 2桁("02"の部分)で表記します.
変数を複数表示したい場合は以下のように書きます.
print("{0:02x}{1:02x}".format(buf[1], buf[2]))
まとめ
with open(file_path, "rb") as f:
buf = f.read(byteSize)
print("{0:02x}".format(buf[0]))
以上です(笑)
おわりに
内容の薄い記事になってしまいました. もっと内容を広く, 体系的にまとめるべきですね.