1

假设您有两组无序的校验和,一组大小为 N,一组大小为 M。根据比较它们的算法,您甚至可能不知道大小,但可以比较 N != M 以快速中止。

用于校验和的散列函数有一定的碰撞机会,作为外行,我愚蠢地称之为“强度”。有没有办法获取两组校验和,全部由相同的哈希函数制成,并快速比较它们(因此比较元素与元素是正确的)两组之间发生冲突的基本机会与两个单独的校验和之间存在相同的基本机会?

例如,一种方法是通过对集合中的所有校验和进行异或来计算“集合校验和”。这个新的单个散列用于与其他集合的散列进行比较,这意味着不再需要存储大小。特别是因为它可以通过与集合的校验和进行异或来修改元素校验和的添加/删除,而无需重新计算整个事物。但是,与所有原始校验和的蛮力比较相比,这会降低集合校验和的“强度”吗?有没有一种方法可以合并一个集合的校验和,它不会降低“强度”(尽可能多?)但仍然没有直接比较集合元素的校验和那么复杂?

4

1 回答 1

1

在我最初的评论之后,我开始思考它背后的数学原理。这就是我想出的。我不是专家,所以请随时进行更正。注意:这一切都假设您的哈希函数是均匀分布的,因为它应该是。

基本上,校验和中的位数越多,碰撞的可能性就越低。文件越多,越高。

首先,让我们找出与一对文件进行异或运算后发生冲突的几率。我们将首先使用小数字,因此假设我们的校验和是 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)

您将一堆校验和异或的方法可能很好。

于 2013-10-02T21:39:30.270 回答