完美/理想的哈希来隔离字谜

时间:2013-08-10 13:07:17

标签: c hash anagram entropy

为了加快测试字谜字符串的快速行为,我came up with基于素数的哈希方案 - 虽然它看起来像我wasn't the first

基本思想是将字母映射到素数,并计算这些素数的乘积。任何重新排列的字母都会有相同的产品,如果结果可以任意大,那么其他字母的组合也不会产生相同的结果。

我最初设想这是只是哈希。最终产品会溢出并开始为其他字母组合添加别名。但是,通过将最频繁的字母映射到最小的素数,产品生长缓慢并且通常可以完全避免溢出。在这种情况下,我们得到一个完美的哈希,给出明确的正面和负面结果,无需额外的测试。

值得注意的是,它在溢出之前没有非常有效地填充编码空间。没有结果会有任何大于103的素数因子,并且小素数的分布是固定的,并不一定与字母频率匹配。

现在我想知道是否有比这更好的东西。在剩下的情况下,包含更多结果的东西具有完美的散列并且具有强烈的分布。

我能想到的最密集的编码方案是对字母进行排序,然后用熵编码器将它们打包成一个单词。在该方案中,由于应用于每个位置的范围约束,字母频率显然会极大地偏向(例如,以z开始的排序数组的可能性显着低于以z结尾的排序数组的可能性。)

这听起来像是一大堆工作 - 而且我看不出它能保证在溢出的情况下提供良好的分配。

也许有一组更好的因素来映射字母,以及更好的方法来检测何时开始出现混叠风险。还是一个不依赖于乘法的哈希方案?什么东西很容易计算?

那就是:

  • 尽可能多的真实世界输入的完美哈希(对于一些合理的位数)。
  • 对剩余案例的强烈哈希,以区分这两种情况。
  • 易于计算。

英语语言限制(26个具有典型英语单词结构的字母)会很好。多字节编码方案是另一个问题。

C代码首选,因为我理解它。

2 个答案:

答案 0 :(得分:1)

如果您使用大小为m的字母表的n位哈希值,则可以使用我所描述的方法here为长达(n-m)个字符的字谜提供唯一的哈希值。这样就不需要进行碰撞检测,但它会根据字母表的大小和可用空间来限制字数。

为了允许任何长度的单词,我将使用n-1位为长度为(n-m-1)个字符的单词执行该散列,并保存最后一位以表示该单词为m个字符或更长。在这些情况下,您将使用剩余的n-1位作为素数或其他散列算法,但当然,只要您在这些存储桶中有多个单词,就可以进行碰撞检测。由于在实际应用中大多数单词将占用较短的单词长度,因此您将大大减少较长单词所需的碰撞检测。

答案 1 :(得分:0)

在此处实施了flancor的答案:https://github.com/sh1boot/anagram/blob/master/bitgram.c

使用http://ftp.debian.org/debian/pool/main/s/scowl/wbritish_7.1-1_all.deb作为 字典,我得到以下比例的完美代码(积极的和 来自哈希比较的负匹配)使用这些编码方案:

order  | frequency|  alphabet| frequency|  alphabet| frequency
code   |    prime |    unary |    unary |  huffman |  huffman
-------|----------|----------|----------|----------|----------
64-bit |   93.95% |  100.00% |  100.00% |  100.00% |  100.00%
32-bit |   24.60% |   69.14% |   74.23% |   86.57% |   90.58%
28-bit |   15.20% |   41.75% |   60.27% |   68.16% |   74.34%
24-bit |    8.21% |   13.14% |   38.55% |   42.67% |   50.34%
20-bit |    3.72% |    3.35% |   16.73% |   19.41% |   25.59%
16-bit |    1.31% |    0.82% |    4.86% |    5.51% |    9.18%

这表明任何比特打包直方图编码的变体都可以捕获 完整的64位哈希中的整本字典,以及超过三分之二的字典 32位哈希中的字典;而主要产品计划正在努力 即使在64位也达到100%,甚至不能覆盖四分之一的字典 一个32位的哈希。

这个列表确实包含很多撇号,但几乎所有(但不是 所有)64位未命中包括撇号。把这个角色放在其中 频率表中的适当位置可能会有所帮助。

一些additional测试:

频率/霍夫曼,溢出:

88aff7eb53ef9940: Pneumonoultramicroscopicsilicovolcanoconiosis

频率/霍夫曼,64位完美:

17415fbc30c2ebf7: Chargoggagoggmanchauggagoggchaubunagungamaugg
018a6b5dda873fba: Supercalifragilisticexpialidocious
00021ae1bcf50dba: Pseudopseudohypoparathyroidism
00070003dd83b5fb: Floccinaucinihilipilification
00002b800ebbdf7a: Antidisestablishmentarianism
000006c6ab75b3f9: Honorificabilitudinitatibus
0000000421b2ad94: glyptoperichthys
0000000201b2ad94: pterygoplichtys

可能的情况是,应该针对可能落在边界附近的单词进行调整,因为它们可能具有强烈影响其分布的属性(例如,原始语言),并且使得更短的单词更长。直到它们溢出为止。