我正在研究一个哈希冲突会成为问题的系统。本质上,有一个系统引用哈希表+树结构中的项目。然而,所讨论的系统首先将包含结构中路径的文本文件编译成包含散列值的二进制文件。这样做是出于性能原因。然而,由于这种冲突非常糟糕,因为该结构不能存储具有相同哈希值的 2 个项目;要求物品的部分没有足够的信息来知道它需要哪一个。
我最初的想法是,使用 2 种不同算法或两次使用相同算法的 2 次哈希使用 2 种盐会更耐碰撞。对于不同的散列算法,两个项目具有相同的散列是不太可能的。
出于空间原因,我希望将哈希值保持为 32 位,所以我想我可以切换到使用两种 16 位算法而不是一种 32 位算法。但这不会增加可能的哈希值的范围......
我知道切换到两个 32 位哈希会更耐冲突,但我想知道切换到 2 个 16 位哈希是否至少比单个 32 位哈希有一些收益?我不是最喜欢数学的人,所以我什至不知道如何开始检查答案,除了强加它......
系统的一些背景:
项目由人类命名,它们不是随机字符串,通常由单词、字母和数字组成,没有空格。它是一个嵌套的哈希结构,所以如果你有类似 { a => { b => { c => 'blah' }}} 的东西,你会通过获取 a/b/c 的值来获得值 'blah',编译后的请求将是立即序列中的 3 个哈希值,a、b 和 c 的哈希值。
只有在给定级别发生碰撞时才会出现问题。顶层项目和较低层项目之间的冲突是正常的。你可以有 { a => {a => {...}}},几乎可以保证不同级别的碰撞(不是问题)。
实际上,任何给定级别的哈希值都可能少于 100 个,并且在同一级别上没有一个是重复的。
为了测试我采用的散列算法(忘记是哪个,但我没有发明它)我下载了整个 CPAN Perl 模块列表,将所有命名空间/模块拆分为唯一的单词,最后对每一个进行散列搜索以查找冲突,我遇到了 0碰撞。这意味着该算法对于 CPAN 命名空间列表中的每个唯一单词都有不同的哈希值(或者我做错了)。这对我来说似乎已经足够好了,但它仍然在我的脑海中挥之不去。