如何将64位哈希值缩短到48位值?

时间:2015-10-02 17:44:20

标签: c algorithm math hash uuid

我已经在库中有64位散列函数(C编码),但我只需要48位。我需要将64位散列值减少到48位值,但它必须以安全的方式才能最小化冲突。

散列函数是一个非常好的64位散列函数。它已经通过SMHasher(" DieHarder"哈希测试)进行了测试,并且证明比Murmur2更好。据我的同事们说,在lib中实现64位散列的算法是xxHash,用SMHasher测试并得到Q.Score为10!对于那些想要查看它的人,xxHash的源代码可以在github.com上找到:github.com/Cyan4973/xxHash/releases/latest

基本思想是让64位散列值(或其中一部分)中的所有位对产生的48位散列值产生影响。有没有办法做到这一点?

[后期编辑]:
所以我实现了自己的48位(准)-UUID发生器 请在此处查看完整的解决方案(包括源代码):https://stackoverflow.com/a/47895889/4731718

3 个答案:

答案 0 :(得分:11)

如果64位散列是好的,那么选择任何48位也将是一个很好的散列。 @Lee Daniel。当然,信息丢失了,不可逆转。

unsigned long long Mask48 = 0xFFFFFFFFFFFFu;
unsigned long long hash48 = hash64 & Mask48;

如果64位散列函数较弱,则由pow(2,48)下的最大素数修改。一些桶将丢失。这不会伤害好哈希,但肯定会使弱哈哈变得更好。

unsigned long long LargestPrime48 = 281474976710597u;  // FFFFFFFFFFC5
unsigned long long hash48 = hash64 % LargestPrime48;

答案 1 :(得分:2)

hash >>= 16;

但如果你觉得更好地保留其他16位只是使用XOR。

hash = (hash >> 16) ^ (hash & 0xFFFF);

答案 2 :(得分:2)

据我所知,目前还没有48位哈希算法。 48位变量类型也不存在,所以无论如何这是一个非常奇怪的设计选择。

当然,你不能将64位散列缩减到48位而不会丢失,安全散列无论如何都是完全不同的主题。您可以使用像CRC32这样的常见32位散列函数,只需要16个空位。或者甚至组合一个32位和16位,但这看起来真的很奇怪。从碰撞安全的角度来看,这甚至不是一件事,我不想听到有经验的人对此的反应。

我的建议:使用标准尺寸的已建立哈希算法,不进行实验。无论如何,已经很难提出一个好的哈希算法。没有必要变得有创意,除非你是你所在领域的专家,并且可以处理变化可能产生的影响(这可能是最困难的部分)。