Java中文本字符串的64位哈希函数是什么?
我正在寻找一个哈希函数:
- 很好地散列文本字符串(例如,很少的冲突)
- 用Java编写,并广泛使用
- 奖励:适用于多个字段(而不是我连接它们并在连接字符串上应用哈希)
- 奖励:具有 128 位变体。
- 优点:不是 CPU 密集型的。
我正在寻找一个哈希函数:
你为什么不使用默认值的变体(一些非常聪明的人肯定会努力提高效率 - 更不用说已经看过这段代码的成千上万的开发人员眼睛)?long
String.hashCode()
// adapted from String.hashCode()
public static long hash(String string) {
long h = 1125899906842597L; // prime
int len = string.length();
for (int i = 0; i < len; i++) {
h = 31*h + string.charAt(i);
}
return h;
}
如果你正在寻找更多的位,你可以使用编辑:BigInteger。
正如我在对@brianegge答案的评论中提到的,对于超过32位的哈希,没有太多用例,对于超过64位的哈希,很可能没有一个用例:
我可以想象一个巨大的哈希表分布在几十台服务器上,可能存储着数百亿个映射。对于这种情况,@brianegge在这里仍然有一个有效的观点:32位允许2 ^ 32(约43亿)不同的哈希键。假设有一个强大的算法,你仍然应该有相当多的冲突。使用64位(18,446,744,073亿个不同的密钥),无论您需要它做什么疯狂的场景,您都可以节省。但是,考虑128位密钥(340,282,366,920,938,463,463,374,607,431十亿个可能的密钥)的用例几乎是不可能的。
要组合多个字段的哈希值,只需执行XOR乘以素数并将它们相加:
long hash = MyHash.hash(string1) * 31 + MyHash.hash(string2);
小素数在那里是为了避免切换值的哈希代码相等,即{'foo','bar'}和{'bar','foo'}不相等,应该有不同的哈希码。XOR 是坏的,因为如果两个值都相等,它将返回 0。因此,{'foo','foo'} 和 {'bar','bar'} 将具有相同的哈希代码。
今天(2018)的答案。SipHash.
它将比这里的大多数答案快得多,并且质量比所有答案都高得多。
番石榴图书馆有一个:https://google.github.io/guava/releases/23.0/api/docs/com/google/common/hash/Hashing.html#sipHash24-