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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将64位哈希值缩短到48位值?相关的知识,希望对你有一定的参考价值。

我已经在库中有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

答案

如果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;
另一答案
hash >>= 16;

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

hash = (hash >> 16) ^ (hash & 0xFFFF);
另一答案

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

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

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

以上是关于如何将64位哈希值缩短到48位值?的主要内容,如果未能解决你的问题,请参考以下文章

x86_64 无法将 64 位值添加到 rax,“'add' 上的操作数不匹配”

从顶点到片段着色器的平滑 64 位输入 - “错误 C7570:64 位输入应该是平坦的”

如何在x86 ASM中原子地移动64位值?

Z80汇编:如何将带符号的8位值添加到16位寄存器?

并行/组合多个 64 位值的按位排列

将 Int64 转换为 UUID