我需要生成一个哈希值,用于Java中数十亿条记录的唯一性。麻烦的是,我只有16位数字可供使用。在研究这个时,我发现了32位散列的算法,它返回Java整数。但这太小了,因为它只有+ / 20亿的范围,而且会有更多的记录。我不能去64位哈希,因为这会给我数值太大(+ / 4 quintillion,或19位)。麻烦的是,我正在处理遗留系统,迫使我进入16位静态密钥长度。
连连呢?我知道没有哈希函数可以保证唯一性,但我需要一个适合这些限制的好的函数。
由于
答案 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。