技術メモ

ネットワークエンジニアがpython, perl等々を気楽に使うための覚え書き

python hashlibによるMD5/SHA-1/SHA-256 File validation

MD5/SHA-1/SHA-256をまとめて計算、そしてCSV出力もサポートするPythonスクリプト(Windows版のPython3.4で作成)。

メモ

  • 使い方は、対象ファイルをglob形式で指定(複数可)。
  • hash.update()で使うblocksizeの選択に注意(スクリプトでは、デフォルト2047を定義)。
C:\>get_digest.py -h
usage: get_digest.py [-h] [-c] glob_pattern [glob_pattern ...]

positional arguments:
  glob_pattern  glob pattern(eg. *.bin *.log)

optional arguments:
  -h, --help    show this help message and exit
  -c, --csv     switch to csv output

get_digest.py

#!/usr/bin/env python3
import os
import glob
import argparse
import hashlib

def get_digest(file_, blocksize = 2047):
    md5 = hashlib.md5()
    sha1 = hashlib.sha1()
    sha256 = hashlib.sha256()
    with open(file_, 'rb') as f:
        while True:
            buf = f.read(blocksize)
            if not buf: break
            md5.update(buf)
            sha1.update(buf)
            sha256.update(buf)
    return {
        'md5'   : md5.hexdigest(),
        'sha1'  : sha1.hexdigest(),
        'sha256': sha256.hexdigest(),
    }

parser = argparse.ArgumentParser()
parser.add_argument('glob_pattern', action = 'store', nargs = '+',
                    help = 'glob pattern(eg. *.bin *.log)')
parser.add_argument('-c', '--csv', dest = 'is_csv', action = 'store_true',
                    help = 'switch to csv output')
args = parser.parse_args()

files = []
for pattern in args.glob_pattern:
    files.extend(glob.glob(pattern))

if args.is_csv:
    print('"FILE","SIZE","MD5","SHA-1","SHA-256"')
    template = '"{file}","{size}","{md5}","{sha1}","{sha256}"'
else:
    template = """
FILE    : {file} ({size} bytes)
MD5     : {md5}
SHA-1   : {sha1}
SHA-256 : {sha256}"""

for file_ in files:
    if os.path.isdir(file_):
        print("{} is a directory.".format(file_))
        continue
    print(
        template.format(
            file = os.path.abspath(file_),
            size = os.path.getsize(file_),
            **get_digest(file_)
        )
    )