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

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

散列函数是一个非常好的64位散列函数。 它已经通过SMHasher(“DieHarder”哈希测试)进行了测试,并且certificate比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 。

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

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

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

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

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

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

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

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

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