我需要一个字符串(字节)的哈希函数
碰撞率低(即使是短弦)
可以快速计算(O(n)
时间是必须的,但我希望它尽可能快)
鉴于hash(string1)
和hash(string2)
,计算hash(append(string1, string2))
可以在O(1)
。
到目前为止我能想出的最好的是:(在Java伪代码中)
public static int[] HASH_ENTROPY = new int[] {...} // 255 large prime numbers
public int hash()
int hash = 0;
for (int i=0; i < this.array.length; i++)
hash += HASH_ENTROPY[this.array[i] + 128];
return hash;
有没有更好的算法?这个与#1和#3表现良好,但我想知道 如果它必须访问数组中的随机元素太慢。
答案 0 :(得分:1)
我建议您使用:
public uint32_t hash()
uint32_t hash = 0x1f351f35; // 2x Barker code
for (int i=0; i < this.array.length; i++) {
char c = this.array[i];
hash = ((hash << 1) | (hash >> 31)) + (HASH_ENTROPY[(uint8_t)(hash + c)] ^ c);
}
return hash;
答案 1 :(得分:0)
此外,如果您需要快速计算时间,可以考虑另一个哈希函数:
public uint32_t hash()
uint32_t hash = 0x1f351f35; // 2x Barker code
for (int i=0; i < this.array.length; i++) {
hash += (hash << 4) + this.array[i];
}
return hash;
重要的: 以前的哈希函数使用熵数组;你可以在每个程序开始时通过随机值填充这个数组,这样就会有通用哈希,抵抗外部攻击,当外面的人特别生成许多具有相同哈希的字符串时,产生冲突和服务的DOS。这个功能很快,但不能抵御邪恶的攻击。</ p>