使用Precision的字符串到整数哈希函数

时间:2009-06-18 05:14:26

标签: c++ hash

我想将一个char数组哈希到一个int或long。结果值必须符合给定的精度值。 我一直在使用的功能如下:

int GetHash(const char* zKey, int iPrecision /*= 6*/)
{
        /////FROM : http://courses.cs.vt.edu/~cs2604/spring02/Projects/4/elfhash.cpp

        unsigned long h = 0;
        long M = pow(10, iPrecision);

        while(*zKey)
        {
                h = (h << 4) + *zKey++;
                unsigned long g = h & 0xF0000000L;
                if (g) h ^= g >> 24;
                h &= ~g;
        }            

        return (int) (h % M);
}

要哈希的字符串类似于“SAEUI1210.00000010_1”。

但是,在某些情况下会产生重复值。 是否有任何好的替代品不会为不同的字符串值复制相同的散列。

4 个答案:

答案 0 :(得分:13)

散列的定义是它为某些值生成重复值,因为散列值范围小于散列数据的空间。

理论上,32位散列具有足够的范围来散列所有~6个字符串(仅限A-Z,a-z,0-9),而不会导致冲突。在实践中,散列并不是输入的完美排列。给定32位散列,由于birthday paradox,在散列~16位随机输入后,您可能会遇到散列冲突。

给定一组静态数据值,总是可以构造一个专门为它们设计的哈希函数,它永远不会与自身发生冲突(当然,它的输出大小至少为log(|data set|)。但是,它要求您提前知道所有可能的数据值。这称为perfect hashing

话虽如此,here是一些可以让你开始的选择(它们旨在最大限度地减少碰撞)

答案 1 :(得分:2)

每个哈希都会发生冲突。期。这称为Birthday Problem

您可能想要检查加密功能,如MD5(相对较快,您不关心它是不安全的)但它也会发生冲突。

答案 2 :(得分:2)

哈希为不同的输入生成相同的值 - 这就是他们所做的。您所能做的就是创建一个具有足够分布或位深度(或两者)的散列函数,以最大限度地减少这些冲突。由于你有这个额外的精度约束(0-5?),那么你将更频繁地碰撞。

答案 3 :(得分:1)

MD5SHA。有许多开放的实现,结果不太可能产生重复的结果。