単純に2ファイルを比較する部分は、
2007-03-15 – 当面C#と.NETな記録
http://d.hatena.ne.jp/siokoshou/20070315
にある FastDiff のコードをコピーして利用。
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 であれば一致、大きければそれだけファイルが違うという感じ。
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 ファイルで当たっていけばよいので、適当な閾値をつけて類似ファイルを見つけるか、ヒストグラムを出して、一致する自動的に閾値を見つけるか、という感じで。続きは明日。
