我正在尝试找到一个(哈希)函数,该函数采用32位或64位的无符号整数,并将其再次映射到同一类型。
它应该是双射的,快速的。
附加财产:
对于任何n,应将0到n的序列“均匀”映射到图像上。 意思是,如果我将图像分成k个相同大的子集,它们应该大致相等,因为k <&lt;&lt; Ñ
答案 0 :(得分:0)
我正在尝试找到一个(哈希)函数,该函数采用32位或64位的无符号整数,并将其再次映射到同一类型。
它应该是双射的,快速的。
嗯,满足0碰撞的函数是身份函数,即
uint64_t hash(uint64_t inp) {
return inp;
}
您的其他属性:
对于任何n,应将0到n的序列“均匀”映射到图像上。
嗯,所以身份不会这样做,因为前n个数字当然是紧凑的。但是:
位反转可以解决问题!
因此,不要返回相同的数字,只需返回它们的位反转版本。
位反转通常不是快速操作,除非你有技巧和/或CPU指令可以帮助你。
编辑:啊等等,我记得Knuth已经提出了一个功能,它应该比你的平均哈希impl快得多。
答案 1 :(得分:0)
假设mult
是奇数(T
的范围是2的幂,就像在任何现代处理器上一样),
template <T>
auto linear_congruential_hash(T mult, T incr) {
static_assert(std::is_integral<T>::value,
"template argument must be an integral type");
return [mult, incr](T n) -> T {
return mult * n + incr;
}
}
是双射的。如果mult
接近T
的上限,那么函数也将接近满足您的一致性要求(只是避免使mult
使得它的一些小的倍数太接近为0,例如0x7fffffffU
会很糟糕)。所以,举一个具体的例子,像linear_congruential_hash<uint32_t>(0x68832099U, 0x30571005U)
这样的东西应该可以很好地运作。
答案 2 :(得分:-1)
这符合您的所有要求:
unsigned int identity(unsigned int x) {
return x;
}