【问题标题】:How to quickly determine if two sets of checksums are equal, with the same "strength" as the individual checksums如何快速确定两组校验和是否相等,与单个校验和具有相同的“强度”
【发布时间】:2013-10-09 06:36:48
【问题描述】:

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

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

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

【问题讨论】:

  • 这里的强度有多重要?发生碰撞的几率仍然很低。如果您使用的是大小合适的校验和,我不会太担心。
  • @Geobits 这不是真的,我觉得很安全。我只是好奇是否有一些我没有注意到的聪明东西。

标签: algorithm hash language-agnostic checksum


【解决方案1】:

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

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

首先,让我们找出一对经过异或运算的文件发生冲突的几率。我们将首先处理小数字,因此假设我们的校验和是 4 位 (0-15),我们将其命名为 n

有两个和,比特总数2n(8),所以总共有2^(2n)(256) 个可能性。但是,我们只对碰撞感兴趣。要碰撞 XOR,您需要翻转两个和中的 same 位。只有2^n(16) 种方法可以做到这一点,因为我们使用的是n bits。

所以,碰撞的总体概率是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 幂。

因此,对于 10 个具有 4 位校验和的文件,我们会得到非常糟糕的结果:

(15/16) ^ 9 = 55.92% 的几率不发生碰撞

即使我们增加文件数量,当我们添加位时,情况也会迅速好转。

对于 10 个具有 8 位校验和的文件:

(255/256) ^ 9 = 96.54%

对于 16 位的 100/1000 个文件:

(65536/65536) ^ 99 = 99.85%

(65536/65536) ^ 999 = 98.49%

如您所见,我们仍在使用小校验和。如果您使用 >= 32 位的任何内容,当我尝试对其进行数学运算时,我的计算器就会出现浮点舍入错误。

TL,DR:

其中n 是校验和位数,f 是每个集合中的文件数:

nonCollisionChance = ( ((2^n)-1) / (2^n) ) ^ (f-1)
collisionChance = 1 - ( ((2^n)-1) / (2^n) ) ^ (f-1)

你对一堆校验和进行异或的方法可能很好。

【讨论】:

    猜你喜欢
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2011-09-16
    相关资源
    最近更新 更多