对于短字符串来说,这是一个很好的哈希函数吗?

Is this a good hashing function for short strings?

本文关键字:很好 一个 哈希 函数 字符串 于短      更新时间:2023-10-16

对于 10-50 个字符的字符串:

double hash(const std::string & str)
{
double result = 0;
int n=str.length();
for(int i=0;i<n;i++)
{
result += (str[i] - '@')*pow(256.0,i);
}
return result;
}

这可以用于生产代码吗?

  • 通过 ILP 提高与 std::hash 一起使用时哈希的总吞吐量
  • 正确性/唯一性
  • 可扩展性

新版本评论:

double hash(const std::string & str)
{
double result = 0;
int n=str.length();
// maybe using multiple adders to do concurrently multiple chars
// since they are not dependent
for(int i=0;i<n;i++)
{
result += lookupCharDoubleType[str[i]]*lookupPow[i];
}
return result;
}

另一个评论的另一个版本:

double hash(const std::string & str)
{
double result = 0;
int n=str.length();
for(int i=0;i<n;i++)
{
result = result * 256.0 + lookupCharDoubleType[str[i]];
}
return result;
}

对于短字符串来说,这是一个很好的哈希函数吗?

不,这不是唯一性的好哈希值。您基本上是将字符串映射到double上。对于长度为 50 个字符的字符串,您将获得一个256 ^^ 50量级的值,即 2.58e120。这完全在双精度的范围内,即 1.7e308,但你必须明白,double并不能准确表示数字——毕竟它只有 8 个字节长。

您的代码将字符串映射到double,就好像字符是 256 进制数字一样,第一个字符是最不重要的数字:

字符串hello映射如下:

'h' * 256^^0 + 'e'*256^^1 + 'l' * 256^^2 + 'l' * 256^^3 + 'o' * 256^^4

对于大于几个字节的字符串,最后字符将是结果中最重要的部分,所有其他字符将被完全删除,因为double没有表示所有这些位的精度。

最终结果是你的哈希函数只会考虑最后几个字符。每当字符串中的任何字符更改时,一个好的哈希函数都应该更改,因此相似但不完全相同的字符串极不可能具有相同的哈希值。对于您的函数,只要最后几个字符相同,哈希值就可能相同。