64位无符号散列函数

时间:2012-11-27 09:11:15

标签: java algorithm math

我有64位无符号整数(范围从0到2 ^ 63 - 1),我想将它们哈希为32位无符号整数(0到2 ^ 31 - 1范围)。

数据遵循Uniform Distribution。任何人都可以建议一个散列函数,为这个分布提供少量的碰撞(可能有一些碰撞发生的概率)?

3 个答案:

答案 0 :(得分:2)

如果它的分布真的是一致的,那么只需取较低的n位(散列值的宽度)。这意味着,最坏的情况是你可以在一个桶中有2个 N-n 元素。 (此处N表示原始数字的宽度)

注意:刚刚看到@JanDvorak已经建议这个(在我回答之前),使用modulo 2 n 相当于取下n位。

如果这实际上是关于 64位无符号整数被散列为 32位无符号整数,那么正确的范围将是 [0; 2 64 -1] [0; 2 32 -1] ,最多 2 32 单个哈希上的冲突。但是,在Java中,没有无符号整数......

如果这是分别使用带符号64和32位整数值的正半部分,那么您的范围值是正确的,并且您仍然会有 2 32 碰撞最坏的情况。

答案 1 :(得分:1)

对于这样一个简单的分布,任何合理的散列函数都适合。要确保,只需尝试(int)(longvalue+(longvalue>>32))并计算碰撞次数。如果你只需要31位,那么make res&0x7fffffff(为什么你的压力值是无符号的?31位int和63位长适合有符号和无符号范围)。

答案 2 :(得分:1)

如果你已经拥有合适的长度和均匀的位分布,为什么要进行散列?我假设你有一些安全要求?请分享。

如果它是您正在寻找的标准哈希,请考虑SHA-1:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
//Some more imports

MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(data);
byte[] hash = md.digest());