我正在寻找一系列哈希函数F1,... Fn,其中每个Fi映射[0,1]中的任何键。我的第一个实现是Fi(k)= F(k,i)= hash(i,hash(k,0)),.这里hash是这里提供的hashlittle函数(http://burtleburtle.net/bob/c/lookup3.c)。我没有深入了解hashlittle究竟是什么。
正如敏锐的读者会注意到的那样,这将失败。我的问题是如何有效地实现这一目标。我的目标是平均减少最大的i 对于任何给定的k1,k2对,Fi(k1)== Fi(k2)。 当然它也应该很快..
答案 0 :(得分:3)
好吧,我已经看了一下。
uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
{
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
编写u.ptr然后读取u.i是未定义的行为。
修改强>
我想我现在明白了。您基本上需要将两个参数作为输入的哈希函数。您可以使用几乎任何哈希函数。
散列函数获取任意位大小的数据包,并将其转换为固定位大小的数据包:
hashval = Hash(data, len);
您需要一个函数,在转换中给出并使用其他参数,对吗?
hashval = Hash(data, len, addval);
最简单的方法是将附加值连接到数据包:
memcpy((char *)data + len, &addval, sizeof(addval));
hashval = Hash(data, len + sizeof(addval));
如果您有源可用,另一种方法是修改它以使用新参数作为内部哈希计算的初始化。这是在hashlittle中完成的。
Before:
uint32_t Hash (const void *data, size_t len)
{
uint32_t hashval = 0;
....
return (hashval);
}
After:
uint32_t Hash (const void *data, size_t len, uint32_t init)
{
uint32_t hashval = init;
....
return (hashval);
}
这个选项可能有点困难,因为内部状态可能远远超过单个hashval,初始化可能非常复杂,而不是简单地使用0.在hashlittle中它是:
/* Set up the internal state */
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;