MD5ハッシュ値を表示するスクリプトサンプル

最近C言語の勉強を始めたbonlifeです。先日、ベンダーから会社で使っているミドルウェアのPatchが送られてきた時、MD5ハッシュ値がメールに記載されていました。今まであまり気にしたことはなかったのですが、せっかくなので、簡単なスクリプトを書いて、確認してみることにしました。得意な言語がないので、色々と試しちゃいましたよ。(ファイルのMD5ハッシュ値を調べることなんて滅多にないとは思いますが…。)

  • Perlのサンプル
#! /usr/local/bin/perl

use strict;
use warnings;

use Digest::MD5 qw(md5 md5_hex);

my @files;

foreach (@ARGV) {
    push @files, glob "$_" ;
}

foreach (@files) {
    eval {
        open (FH, $_) or die "Can't open '$_' : $!";
        binmode(FH);
        print Digest::MD5->new->addfile(*FH)->hexdigest, " : $_\n";
        close(FH);
    };
    if ($@) {
        print "error occured while processing '$_' : $!\n";
    }
}
  • Rubyのサンプル
require 'digest/md5'

ARGV.each {|file|

  begin
    print Digest::MD5.new(File.open(file,'rb').read), " : ", file , "\n"
  rescue
    abort(("error occured while processing '" << file << "' : " << $!))
  end

}
# coding: utf-8
import sys
import glob
import md5

# [参考URL]
# http://white.s151.xrea.com/wiki/index.php?cmd=read&page=memo%2Fpython%2Fmd5

def getMd5(path):
    m = md5.new()
    for f in open(path,'rb'):
        m.update(f)
#    m.update(open(path,'rb').read())
    return m.hexdigest()

for i in range(1,len(sys.argv)):
    for f in glob.glob(sys.argv[i]):
        try:
            print getMd5(f), ":", f
        except:
            print "error occured while processing '" + f + "' :", sys.exc_info()[0]
  • PHPのサンプル
<?php

for ( $i = 1; $i < count($argv) ; $i++ ){
    foreach (glob($argv[$i]) as $file){
        print md5_file($file) . " : $file\n";
    }
}

?>

全て結果は同じになりました!という当たり前の結果にちょっと感動したりして(苦笑)。
PHPコマンドラインで実行するのってやっぱり違和感ありますね。専用の関数があって一番楽なんですけどね。引数の1番目をどう扱うのかが言語によって違ってたりするのを体感できて面白かったです。Pythonだけ(他の人のスクリプトを参考にして)関数を定義していたり、バランスが良くないですが、まぁ、ご愛嬌。
ところで、そもそもMD5ハッシュ値ってどういう意味があるんでしょう。よく、ファイルをダウンロードできるところで、そのファイルのMD5ハッシュ値が記載されてたりしますが、改ざんに対しては無防備ですよね。(ファイル書き換えられるぐらいなら、WEBページも同時に書き換えるでしょうし。)DL途中にファイルが壊れなかったことの確認にはなるかしら。
最後に-Mスイッチでモジュール呼び出してる無理矢理感のあるPerlワイライナーも載せておきます。

perl -MDigest::MD5 -e 'foreach (@ARGV) { open (FH, $_) or die "open \"$_\": $! ";binmode(FH);print Digest::MD5->new->addfile(*FH)->hexdigest, " : $_\n";close(FH); }' filename [filename...]
perl -MDigest::MD5 -e "foreach (@ARGV) { open (FH, $_) or die \"open \'$_\' : $! \";binmode(FH);print Digest::MD5->new->addfile(*FH)->hexdigest, \" : $_\n\";close(FH); }" filename [filename...]

そんなこんなで、ワンライナーの中でシングルクォートを使う方法が分からないbonlifeなのでした。(誰かご存知でしたら教えてくださいませ。)