3

我正在建立一个用户可以上传内容的网站。与往常一样,我的目标是统治世界,所以我想避免两次存储同一个文件。例如,如果用户尝试两次上传同一个文件(通过重命名或只是忘记她过去所做的事情)。

我目前的方法是让跟踪每个上传文件的数据库存储有关每个文件的以下信息:

  • 文件大小(以字节为单位)
  • 文件内容的MD5总和
  • SHA1 文件内容总和

然后是这三列的唯一索引。使用两个散列来最小化误报的风险。

所以,我的问题是:两个大小相同的不同(“真实世界”)文件具有相同 MD5SHA1 哈希值的概率是多少?

或者:是否有类似(非)复杂性的更智能方法?

(我知道概率可能取决于文件大小)。

谢谢!

4

3 回答 3

6

对于所有实际目的,两个大小相同的真实文件具有相同 SHA1 哈希的概率为零。已发现 SHA1 的一些弱点,但从 SHA1 哈希和大小 (1) 创建文件在计算能力方面非常昂贵,并且 (2) 会产生垃圾或原始文件。

在混合物中添加 MD5 完全是矫枉过正。如果您不信任 SHA-1,那么更好的选择是切换到SHA-2

如果您真的很偏执,请尝试比较具有相同(大小,SHA1)签名的文件。但是,如果它们相等,则必须完全读取这两个文件。

于 2011-02-16T13:38:29.357 回答
2

我相信存储 MD5SHA1 哈希会增加不必要的复杂性,而不是好的设计。我会说存储 (SHA1, file size) 的元组就足够了。特别是如果您正在创建一个新的社区站点,我会安全地使用该解决方案,并且只有在它成为问题时才创建更聪明的东西。俗话说,过早的优化是万恶之源,是否“优化”值得商榷。

编辑:我没有量化你遇到 MD5+SHA1 碰撞的几率。我会说它是零。通过粗略的信封计算,具有相同(SHA1,MD5)元组的任意文件大小的两个不同文件的几率为2 ^ -288,就我而言为零。必须要求相同的文件大小进一步减少了这一点。

于 2011-02-16T13:30:02.270 回答
0

您可以使用 Rabin 指纹识别算法的 Broders 实现。它的计算速度比 sha1 和 md5 快,并且被证明是抗碰撞的。但是,它被认为不能安全地抵御恶意攻击,有人可能会在不更改指纹本身的情况下故意更改相关文件。如果您只是想检查文件的相似性,这是一个很好的解决方案。

C# 实现,未经测试:

http://www.developpez.net/forums/d863959/dotnet/general-dotnet/contribuez/algorithm-rabin-fingerprint/

于 2014-08-13T10:57:41.077 回答