単純に2ファイルを比較する部分は、
2007-03-15 – 当面C#と.NETな記録
http://d.hatena.ne.jp/siokoshou/20070315
にある FastDiff のコードをコピーして利用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | namespace SampleBinDiff { class Program { static void Main( string [] args) { string srcfile = args[0]; string destfile = args[1]; Program prog = new Program(); prog.Go(srcfile, destfile); } public int Go( string srcfile, string destfile) { string src = BinToString(srcfile); string dest = BinToString(destfile); // DiffResult[] res = FastDiff.DiffChar(src, dest); DiffResult[] res = FastDiff.Diff(src, dest); Console.WriteLine( "count: {0}" , res.Length); int diffcount = 0; foreach ( var di in res) { Console.WriteLine(di.ToString()); if (di.Modified) { diffcount += di.ModifiedLength + di.OriginalLength; } } Console.WriteLine( "diffcount: {0}" , diffcount); return 0; } public string BinToString( string fname ) { BinaryReader br = new BinaryReader(File.Open(fname, FileMode.Open,FileAccess.Read)); byte [] data = new byte [ new FileInfo(fname).Length]; br.Close(); StringBuilder sb = new StringBuilder(); foreach ( byte b in data) { sb.Append(Convert.ToString(b, 16)); sb.Append( "\n" ); // 行単位で比較 } string src = sb.ToString(); return src; } } } |
バイナリ比較のために FastDiff.DiffChar で比較しようと思ったのだけど、あまり思ったような結果が得られないので、無理矢理改行コードを入れて FastDiff.Diff で比較しています。
実行結果は以下のような感じ。ファイル名を2つ指定すると、diffcount という数値を出します。diffcount が 0 であれば一致、大きければそれだけファイルが違うという感じ。
1 2 3 4 5 | Debug>SampleBinDiff ..\..\Program.cs ..\..\Program3.cs count: 2 Common, OrgStart:0, OrgLen:2720, ModStart:0, ModLen:2720 Modified, OrgStart:2720, OrgLen:0, ModStart:2720, ModLen:24 diffcount: 24 |
これを相互 10,000 ファイルで当たっていけばよいので、適当な閾値をつけて類似ファイルを見つけるか、ヒストグラムを出して、一致する自動的に閾値を見つけるか、という感じで。続きは明日。