我的密钥是64位地址,输出是1字节数(0-255)。允许碰撞,但发生碰撞的概率应该很低。此外,假设要插入的元素数量较少,假设不超过255,以尽量减少鸽子洞效应。
地址是程序中函数的地址。
答案 0 :(得分:3)
uint64_t addr = ...
uint8_t hash = addr & 0xFF;
我认为这符合您的所有要求。
答案 1 :(得分:3)
我会将2个LSB(最低有效字节)一起异或,如果这个分布很糟糕,那么添加第3个,依此类推
这背后的基本原理如下:函数地址不均匀分布。问题通常在于较低的(lsb)位。函数通常需要从可被4/8/16整除的地址开始,因此2-4 lsb可能毫无意义。通过与下一个字节进行异或,你应该摆脱大部分这些问题而且它仍然很快。
答案 2 :(得分:1)
我认为,函数地址很可能是对齐的(参见this question, for instance)。这似乎表明您希望跳过最低有效位,具体取决于对齐方式。
所以,也许从位3开始取8位,即跳过最低有效3位(位0到2):
const uint8_t hash = (address >> 3);
通过检查您的地址集,这一点很明显。在十六进制中,观看最右边的数字。
答案 3 :(得分:1)
怎么样:
uint64_t data = 0x12131212121211B12;
uint32_t d1 = (data >> 32) ^ (uint32_t)(data);
uint16_t d2 = (d1 >> 16) ^ (uint16_t)(d1);
uint8_t d3 = (d2 >> 8) ^ (uint8_t)(d2);
return d3;
它将8个字节的所有位与3个移位和3个xor指令组合在一起。