c++ - 这是一个很好的短字符串散列函数吗?
问题描述
对于 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 个字节长。
您的代码将字符串映射到 a double
,就好像字符是 base-256 数字一样,第一个字符是最低有效数字:
字符串hello
映射如下:
'h' * 256^^0 + 'e'*256^^1 + 'l' * 256^^2 + 'l' * 256^^3 + 'o' * 256^^4
对于大于几个字节的字符串,最后一个字符将是结果中最重要的部分,所有其他字符将被完全删除,因为 adouble
没有表示所有这些位的精度。
最终结果是您的哈希函数将只考虑最后几个字符。一个好的散列函数应该在字符串中的任何字符发生变化时发生变化,因此相似但不完全相同的字符串极不可能具有相同的散列值。使用您的函数,只要最后几个字符相同,哈希值就可能相同。
推荐阅读
- node.js - 节点使用 html-pdf npm 返回 SIGSEGV 错误
- java - 如何从 Java 中的不同类返回对象?
- import - Powershell 6.2.3 无法导入 AzureAd 模块
- android - 如何在 Android Gradle 插件上的 R8Transform 之后添加新的 Transform?
- javascript - python烧瓶动态下拉列表
- swift - 如何使用蒙版对象使对象的背面不可见?
- firebase - 添加 firebase 设置后 React Native 构建失败
- python - 模块“app”pylint(模块中没有名称)中没有名称“路由”
- javascript - setAttribute 不是函数
- soap - 手动修改 WSDL 文件