电话号码的哈希功能

时间:2014-10-14 20:01:33

标签: c hash hash-function

我正在构建一个哈希表,其中键是一个电话号码(这里有一些):

6948060987
6960780800
6963208768
6944870406
6947279288
6953691771
6956094283
6947092062
6960086297
6947719197
6951516975
6957531584
6969211184
6963238579
6957054322
6952077216
6956907738

条目数量为200,2000,20000和2000000,条目将是唯一的。

关于表格的大小,我正在关注this回答。

我将电话号码存储为char的数组。我注意到所有数字都以69开头,所以我可以在哈希函数中跳过它们。

我的尝试是获取数字的总和,并使用哈希表中的单元格数量进行模数,但似乎(在纸面上)这是一个不好的函数,因为存在许多冲突。

我应该如何修改哈希函数以获得更好的结果(减少冲突)?

1 个答案:

答案 0 :(得分:3)

为什么你需要一个非标准的哈希函数?

有大量的哈希函数经过充分测试,具有已知的属性,可以适用于任何输入,因此也适用于电话号码,这些电话号码毕竟是ASCII字符串的子集。您的应用程序是如此时间至关重要,以至于您需要设计自己的哈希函数并冒更多冲突的风险吗?如果没有,为什么不使用一个众所周知的哈希函数?

例如,如果您需要具有加密可证明的碰撞阻力的东西,请使用SHA-256(如果需要,可以截断)。如果您不担心对手,请使用universal hashing之类的内容。除非你的问题非常专业,否则你最好使用其他人经过良好测试的哈希算法,而不是试图自己发明一个。

更简单的哈希是the original hash perl used,其工作原理如下:

# Return the hashed value of a string: $hash = perlhash("key")
# (Defined by the PERL_HASH macro in hv.h)
sub perlhash
{
    $hash = 0;
    foreach (split //, shift) {
          $hash = $hash*33 + ord($_);
    }
    return $hash;
}

在英语中,它采用当前哈希值,乘以33,并添加下一个字符的ASCII值。它不是一个很好的哈希,但它很长一段时间都适用于perl。