Excel ファイルの類似検索の続き

単純に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 ファイルで当たっていけばよいので、適当な閾値をつけて類似ファイルを見つけるか、ヒストグラムを出して、一致する自動的に閾値を見つけるか、という感じで。続きは明日。

カテゴリー: C# パーマリンク