数弱の文系大学生によるブログです。

Python、Webデザイン関連の記事を投稿していけたらなと思っています。

備忘録的なブログなので、読みにくい文章だと思います。ご了承ください。

Python3の復習(バイナリデータ)

こんにちは。

かにたまごです。
バイト代が入って新しい参考書を買うまでに復習を完走させたいなぁ・・・なんて思ってます。


さて、今回は

  • バイナリデータ

について、復習していきたいと思います。
正直、頭の中がハテナでいっぱいの単元。


今までのPython3 復習履歴は以下の通り。

  1. 数値・文字列
  2. リスト・タプル
  3. 辞書・集合
  4. if文・while文・for文
  5. 内包表記
  6. 関数
  7. ジェネレータ
  8. デコレータ
  9. 名前空間とスコープ
  10. アンダーバー・アンダースコアの意味
  11. エラー処理:try・except
  12. モジュール・パッケージ
  13. 標準ライブラリ
  14. オブジェクトとクラス①-クラスの定義-
  15. オブジェクトとクラス②-継承-
  16. プロパティ
  17. ポリモーフィズムとダックタイピング
  18. 特殊メソッドとその他諸々
  19. Unicodeとエンコード・デコード
  20. 書式指定
  21. 正規表現

バイナリデータ

珍しくwikipediaに載っていた言葉で大体理解ができたので、載せておく。

バイナリ (binary) とは二進法のことであるが、コンピュータが処理・記憶するために2進化されたファイルまたはその内部表現の形式(バイナリデータ)のことを指して用いることが多い。

コンピュータが扱うすべてのデータはバイナリデータ(バイトの並び)であり、プレーンテキスト(または単にテキスト)もバイナリデータの一種ではあるが、通常バイナリとテキストは対比して用いられる。

コンピュータに理解できる形(二進数)で表現されたデータをバイナリデータと呼ぶのか。

  • bytesとbytearray

bytesがイミュータブル(変更不可)なのに対して、bytearrayはミュータブル(変更可)。

blist = range(10)

result = bytes(blist)
print("TYPE: {}\n{}".format(type(result), result))

result = bytearray(blist)
print("TYPE: {}\n{}".format(type(result), result))
TYPE: <class 'bytes'>
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t'

TYPE: <class 'bytearray'>
bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t')

変更を加えてみる。

#bytesの場合
result = bytes(blist)
result[0] = 255
print("TYPE: {}\n{}".format(type(result), result))
Traceback (most recent call last):
  File "C:\Users\***\Desktop\Python\Test\blog_test.py", line 1576, in <module>
    result[0] = 255
TypeError: 'bytes' object does not support item assignment
#bytearrayの場合
result = bytearray(blist)
result[0] = 255
print("TYPE: {}\n{}".format(type(result), result))
TYPE: <class 'bytearray'>
bytearray(b'\xff\x01\x02\x03\x04\x05\x06\x07\x08\t')

ほ~ん・・・。

  • structによるバイナリデータの変換

structというモジュールを使うことで、簡単にバイナリデータを処理することができる。

・バイナリ化 -> pack()

・バイナリの解読 -> unpack()

この二つの関数が主要らしい。


試しにPNG画像をバイナリデータとして読み込んだ後、その画像の幅と高さをunpack()で解読してみる。
unpack()の第一引数には、入力されるバイナリデータの解釈方法とデータの組み立て方を指定する。

with open("kaiji.png", "rb") as f:
    import struct
    #有効なPNG画像の先頭8バイトは決まっているらしいので、判定用変数に格納しておく
    png_header = b'\x89PNG\r\n\x1a\n'
    data = f.read()
    #有効かどうか確認
    if data[:8] == png_header:
        #幅は17~20、高さは21~24番目に格納されているらしい
        width, height = struct.unpack(">LL", data[16:24])
        print("種類: PNG画像\n幅: {}px\n高さ: {}px".format(width, height))
    else:
        print("invalid image.")
種類: PNG画像
幅: 427px
高さ: 240px


難しいな・・・。
後々必要になったときに再度勉強しなおそう。


以上です。


参考にさせていただいたサイト:

7. バイナリファイルとはなにか --- テキスト以外のファイルのことである

【Python】ファイルをバイナリモードで読み書き

エンディアン (endian)