题
我工作上的一个程序,搜索整个驱动器给出的文件。目前,我计算MD5hash对于已知的文件,然后扫描的所有文件递归,寻找相匹配。
唯一的问题是,MD5是痛苦的缓慢大型文件。有没有更快的替代方案,我可以使用,同时保留一个非常小的probablity的误报?
所有代码。
谢谢你。
更新
我已经阅读,即使MD5可以相当快的,这盘I/O应的限制因素。这就使我相信,我的代码可能不是最佳的。是否有任何问题与这个方法?
MD5 md5 = MD5.Create();
StringBuilder sb = new StringBuilder();
try
{
using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read))
{
foreach (byte b in md5.ComputeHash(fs))
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
catch (Exception)
{
return "";
}
解决方案
我希望你能检查一MD5比赛只有如果文件已经大小相匹配。
另一个优化做一个快速校的第一1K(或一些其他任意的,但合理的小型号),并确保那些比赛之前工作的整体的文件。
当然,所有这一假设你只是寻找一匹/nomatch的决定为一个特定的文件。
其他提示
无论密码要求、可能的散列冲突的存在,所以没有的散列函数可以用来 保证 这两个文件都是相同的。
我写了类似的代码一段时间了,我得走了相当快速地通过索引的所有文件第一和放弃任何与不同大小。一个快速的散列的比较(的一部分,每个文件),然后再进行关于剩余的条目(比较字节对这一步骤是被证明是较有用的许多文件的类型具有共同的标题具有相同字节开始时文件)。任何文件,都留在这一阶段之后进行,然后检查使用MD5,最后一个字的比较整个文件中如果MD5匹配,只是为了确保内容是相同的。
首先考虑什么是真正的你的瓶颈:散列函数本身而是一个接盘的速度?如果你界盘,改变散列算法不会给你多少。从你介绍我暗示你总是扫描整个盘找到一个比赛,考虑建立索引的第一个然后只匹配给定的散列对指数,这将快很多。
只是读取文件的线性?它似乎相当没意义来读的整个文件中,计算md5hash,然后对比的散列。
阅读该文件的顺序,有几个字节的时间,就能让你放弃的绝大多数的文件,在阅读、说、4个字节。和你想救所有的处理开销计算的散列函数,它不会给你任何东西在你的情况。
如果你已经有的散列的所有文件在开车,它会做出有意义的比较,但是如果你有计算它们在飞行中,有的只是似乎没有任何优势的散列。
我失去了一些东西在这里?什么是哈希买你在这种情况下?
有一个小问题与使用MD5比较文件:有已知的对文件,这些文件 不同的 但是有的 同 MD5。
这意味着可以使用MD5告诉如果文件 不同的 (如果MD5不同的是,该文件必须是不同的),但无法使用MD5告诉如果文件 平等 (如果文件是平等的,MD5必须相同,但如果MD5是平等的,该文件可能或不可能相等)。
你应该使用的散列函数尚未被打破,但(如SHA-1)或(作为@肥皂箱提到的)用MD5仅作为一个快捷的方式找到候选人对于更深入的比较。
参考文献:
使用MD5CryptoServiceProvider和BufferedStream
using (FileStream stream = File.OpenRead(filePath))
{
using (var bufferedStream = new BufferedStream(stream, 1024 * 32))
{
var sha = new MD5CryptoServiceProvider();
byte[] checksum = sha.ComputeHash(bufferedStream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}