好的哈希函数? (32位太小,64位太大)

时间:2011-04-06 12:23:45

标签: java hash md5 apache-commons uniqueidentifier

我需要生成一个哈希值,用于Java中数十亿条记录的唯一性。麻烦的是,我只有16位数字可供使用。在研究这个时,我发现了32位散列的算法,它返回Java整数。但这太小了,因为它只有+ / 20亿的范围,而且会有更多的记录。我不能去64位哈希,因为这会给我数值太大(+ / 4 quintillion,或19位)。麻烦的是,我正在处理遗留系统,迫使我进入16位静态密钥长度。

连连呢?我知道没有哈希函数可以保证唯一性,但我需要一个适合这些限制的好的函数。

由于

5 个答案:

答案 0 :(得分:2)

如果您生成的哈希太大,您可以使用最大键空间来修改它以使其适合。

myhash = hash64bitvalue % 10^16

答案 1 :(得分:2)

如果限制为16位十进制数,则密钥空间包含10 ^ 16个值。 即使您发现哈希在您的数据集上提供均匀分布,由于Birthday Paradox,您将有大约50%的机会在~10 ^ 8项数据上发生冲突,这比您的数据量少一个数量级记录。

这意味着您不能单独使用任何类型的哈希并依赖于唯一性。

一个简单的解决方案是使用全局计数器。如果全局计数器不可行,则可以使用具有预分配范围的计数器。例如,6个最高有效数字表示固定数据源索引,10个最低有效数字包含由该数据源维护的单调计数器。

答案 2 :(得分:1)

您不必以人类可读的形式存储哈希值(十六进制,如您所说)。只需将64位长数据类型(由64位散列函数生成)存储在数据库中,该数据类型仅为8个字节。而不是你被吓到的19个字节。

如果这不是解决方案,请改进遗留系统。


编辑:等等!

64位:2 64 =

18446744073709551616

16个十六进制数:16 16 =

18446744073709551616

准确的合身!因此,请对您的64位哈希进行十六进制表示,然后就可以了。

答案 3 :(得分:1)

所以你的限制是53位?

根据我的理解,哈希码中的位数不影响其值(位的顺序和值完全相互独立)。所以你可以获得64位散列函数,并且只使用它的最后53位。并且您必须为此使用二进制运算(hash64&amp;(1 <&lt;&lt; 54 - 1))而不是算术运算。

答案 4 :(得分:0)

如果您可以保存16个字母数字字符,那么您可以使用十六进制表示并将16 ^ 16位打包成16个字符。 16 ^ 16是2 ^ 64。