LoginSignup
8
8

More than 3 years have passed since last update.

16進数の値が書かれたテキストファイルをバイナリファイルに変換する

Last updated at Posted at 2017-06-04

概要

  • 16進数のテキストファイル --> バイナリファイルに変換する
test.txt
1234567890abcdef

↓バイナリファイル化
test.bin
test.bin.png

この例でpython3.2以降なら、int.to_bytesを使って、

with open("test.txt") as fin,  open("test.bin", "wb") as fout:
    s = fin.read()
    fout.write(int(s,16).to_bytes(len(s)//2,"big"))

とやってしまうのが簡単ですね。

以下は、空白や改行などが入っても対応する場合のコードです。

コード

import re
with open('test.txt', 'r') as fin:
  s = fin.read()
  s = re.sub(r'[\r\n\t ]|0x', '', s)
  bins = [int(a+b,16) for a, b in zip(s[::2], s[1::2])]
  with open('test.bin', 'wb') as fout:
     fout.write(bytearray(bins))

s = re.sub(r'[\r\n\t ]|0x', '', s)
改行/タブ/半角スペースと0xを削除(置換)しています。

bins = [int(a+b,16) for a, b in zip(s[::2], s[1::2])]
aとbのペアで16進数を構成するように取り出して、リストに入れています。

for a, b in zip(s[::2], s[1::2])をもう少し詳しく示すと以下の動きをしています。

In [59]: s = "1234567890abcdef"
    ...: for a, b in zip(s[::2], s[1::2]):
    ...:     print(f"a={a}, b={b}")
a=1, b=2
a=3, b=4
a=5, b=6
a=7, b=8
a=9, b=0
a=a, b=b
a=c, b=d
a=e, b=f

変換例1

概要記載の通り

変換例2

  • スペースや'0x'が入ったケース
test2.txt
0x12 0x34 0x56 0x78 0x90

test2.png

変換例3

  • 2の倍数の文字数でないケース
test3.txt
1234
56789
abc
def

test3.png
* 最後の文字がドロップする('f'が変換されない)

別の手法

@shiracamuさんのpython2での方法を参考にStack Overflowを検索。回答を総合すると、python3ではcodecsを用いて以下のように書けるようだ。

with_codecs.py
import codecs
with open('test.txt', 'r') as fin, open('test.bin', 'wb') as fout:
  s = re.sub(r'[\r\n\t ]|0x', '', fin.read())
  fout.write(bytearray(codecs.getdecoder("hex_codec")(s)[0])

参考

8
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8