在我最初的评论之后,我开始思考它背后的数学原理。这就是我想出的。我不是专家,所以请随时进行更正。注意:这一切都假设您的哈希函数是均匀分布的,因为它应该是。
基本上,校验和中的位数越多,碰撞的可能性就越低。文件越多,越高。
首先,让我们找出与一对文件进行异或运算后发生冲突的几率。我们将首先使用小数字,因此假设我们的校验和是 4 位(0-15),我们将其称为n
.
有两个和,总位数2n
(8),所以总共有2^(2n)
(256) 种可能性。但是,我们只对碰撞感兴趣。要碰撞 XOR,您需要翻转两个和中的相同位。2^n
由于我们使用的是n
位,因此只有(16) 种方法可以做到这一点。
因此,碰撞的总体概率是16/256
,即(2^n) / (2^(2n))
,或者简单地说1/(n^2)
。这意味着不发生碰撞的概率是1 - (1/(n^2))
。因此,对于我们的样本n
,这意味着它只是15/16
安全的,即 93.75%。当然,对于更大的校验和,它会更好。即使是微不足道的n=16
,你也能得到 99.998%
当然,这是一个单一的比较。由于您将它们全部滚动在一起,因此您正在进行f-1
比较,f
文件数在哪里。要以这种方式获得碰撞的总几率,您需要利用f-1
我们在第一步中获得的几率。
因此,对于十个具有 4 位校验和的文件,我们得到了非常糟糕的结果:
(15/16) ^ 9 = 55.92% 的非碰撞几率
随着我们添加位,即使我们增加文件的数量,这种情况也会迅速变得更好。
对于具有 8 位校验和的 10 个文件:
(255/256) ^ 9 = 96.54%
对于 16 位的 100/1000 文件:
(65536/65536) ^ 99 = 99.85%
(65536/65536) ^ 999 = 98.49%
如您所见,我们仍在使用小校验和。如果您使用 >= 32 位的任何内容,那么当我尝试对其进行数学运算时,我的计算器就会出现浮点舍入错误。
长话短说:
其中n
是校验和位数,f
是每组中的文件数:
nonCollisionChance = ( ((2^n)-1) / (2^n) ) ^ (f-1)
collisionChance = 1 - ( ((2^n)-1) / (2^n) ) ^ (f-1)
您将一堆校验和异或的方法可能很好。