tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

ファイルのMD5チェックサムをとる

2つのファイルの差異を見たい、というか、「対象ファイルが違っていたら、上書きコピー」みたいな処理をしたいと思って、最初は単純にサイズだけ見てました。でも対象がバイナリファイル(Excelとか)だから、「サイズだけだとちょっと危ういかなぁ」と思い、「だったらチェックサム取るべ」と思いました。

で、最初に見たのがこれ、
[Microsoft][C#]C#で.md5なファイルを作ってみる。 - home-mg.que.ne.jp - diary

FileStream fs = new FileStream("hogehoge.txt", FileMode.Open);
MD5 md5 = MD5.Create();
byte[] bytes = md5.ComputeHash(fs);
string md5sum = Encoding.Unicode.GetString(bytes) + "\n";
File.WriteAllText("hogehoge.txt.md5", md5sum, Encoding.GetEncoding(932));

パクってみたら、なんか違う。perl で言うところの unpack されてない(?)感じ。

ほかのサイトも見るべ。
[C#] MD5ハッシュ値を算出する(MD5, MD5CryptoServiceProvider, System.Security.Cryptography) - いろいろ備忘録日記

 MD5 md5 = new MD5CryptoServiceProvider();
 Array.ForEach(
                md5.ComputeHash(Encoding.Unicode.GetBytes(original)),
                delegate(byte element){
                    Console.Write(element.ToString("x2");
                }
            );

あ、やっぱり unpack 足りなかったのか。。。

MD5ハッシュ値を計算する - DOBON.NET プログラミング道

byte[] bs = md5.ComputeHash(data);

//byte型配列を16進数の文字列に変換
System.Text.StringBuilder result = new System.Text.StringBuilder();
foreach (byte b in bs)
{
    result.Append(b.ToString("x2"));
}
//ここの部分は次のようにもできる
//string result = BitConverter.ToString(bs).ToLower().Replace("-","");

ん?何この BitConverter って。すげー素敵な変換してるんだけど...

.NET TIPS バイト列と数値を変換するには? - @IT

バイト列と数値との変換を示す前に、バイト列を16進数文字列に変換するBitConverterクラスのToStringメソッドをまず紹介しておこう。このメソッドは、次のサンプル・プログラムにある最初の出力例のように、バイト配列のすべての要素を、ハイフンで区切った2桁ずつの16進数文字列で表示する。

なるほど。素敵です。最終的には、こうなりました。

public static string MD5Sum(FileInfo file) {
        FileStream fs = new FileStream(file.FullName, FileMode.Open);
        string md5sum = BitConverter.ToString(MD5.Create().ComputeHash(fs)).ToLower().Replace("-", "");
        fs.Close();
        return md5sum;
}