继续这个问题:Algorithm for determining a file’s identity
回顾:我正在寻找一种用于确定文件标识的廉价算法,该算法在绝大多数情况下都有效。
我继续实施了一个算法,它为每个文件提供了一个“非常独特的”哈希值。
我的算法的工作方式是:
对于小于某个阈值的文件,我使用标识哈希的完整文件内容。
对于大于阈值的文件,我会随机抽取三个X大小的样本。
我在散列数据中包含了文件大小。 (意味着所有具有不同大小的文件会产生不同的哈希值)
问题:
我应该为N和X选择什么值(我应该选择多少随机样本的大小?)我选择了4个样本,每个样本8K,并且无法算法算法。我发现增加样本量会迅速降低算法的速度(导致搜索非常昂贵)
数学一:我的文件需要多少才能让这个算法爆炸。 (2个具有相同长度的不同文件最终具有相同的哈希值)
优化问题:我有什么方法可以优化我的具体实现以提高吞吐量(我似乎每秒可以在我的系统上做大约100个文件)。
这个实现看起来是否合理?你能想到任何真实世界的例子吗? (我的重点是媒体文件)
相关信息:
感谢您的帮助!
答案 0 :(得分:1)
我会避免像这样的解决方案。我认为,两个媒体文件在压缩格式的相应位置具有相同的大小和相同的数据可能几乎是不可能的。但是如果你必须处理未压缩的图像或波形文件,那么未检测到小的局部变化的可能性就会增大。
所以我认为你应该重新散列整个文件。虽然这看起来很昂贵但是如果您可以访问所有文件可能不会 - 例如,如果您构建文件服务器或类似的东西。你可以逐步构建哈希值。
如果您看到具有唯一文件长度的新文件,只需存储文件长度。如果添加了另一个具有相同长度的文件,则逐块计算两个文件的哈希值,直到它们不同为止。存储文件长度,散列以及散列中包含的文件块数。每当您检测到匹配的文件长度和哈希值并且尚未散列整个文件时,您可以通过添加更多块来扩展哈希值。
关于表现的一些想法。对于小文件,相同文件长度的可能性非常高 - 没有那么多不同的小文件长度。但是散列小文件并不昂贵。
对于较大的文件,由于文件长度越来越多,文件长度碰撞的可能性会降低。对于不同的媒体文件,它们直接超出标题的可能性非常大,因此您只需要对文件开头的一小部分进行哈希处理。
最后,您将确保检测不同的文件(散列冲突除外),因为如果需要,您将散列整个文件。
<强>更新强>
对于电影我会认为文件长度实用独特,但重新编码以适合给定媒体的文件可能会使这个想法无效 - (S)VCD电影将全部处于大约CD-ROM容量的文件长度范围内
但是对于一般的电影文件,我只是从文件中间散列一个块(可能是512字节)。两个不同的电影在同一位置具有相同的图像和声音?除了你操纵文件以使这个测试失败之外,实际上是不可能的。但是你可以很容易地生成文件以使所有确定性采样策略失败 - 所以这应该不重要。
答案 1 :(得分:1)
这是因为它们最有可能与文件不同。如果你考虑BMP,它可能有相当标准的标题(如800x600图像,24位,空值休息),所以你可能想要稍微超过标题以获得差异化数据。问题是标题的大小差异很大。
最后一个块用于将数据附加到原始文件的文件格式。
即便如此,除非你很幸运,否则你会误认为某些文件是相同的(例如SQL Server数据库文件,只需几次插入后它就是1:1备份副本;除了SS确实写了一个时间戳......)
答案 2 :(得分:0)