从boost::hash获取32位哈希值

7

我正在使用boost::hash为字符串获取哈希值,但在Windows 32位和Debian 64位系统上,对于相同的字符串它会给出不同的哈希值。

那么,如何使用boost::hash获取相同的哈希值(32位或64位),而不考虑平台?


假设你依赖于始终获得相同的哈希值,但是 Boost 稍微更改了它们的算法,那么会发生什么? - Mark B
1
在其中一个实例中使用Unicode,而在另一个实例中不使用,这种情况是可能的吗? - Bee
2
boost:hash(hash_value) 返回 std::size_t,因此在 64 位系统中返回 64 位长整型,在 32 位系统中返回 32 位长整型。 - onemouth
@onemouth,size_t大小会导致这样的差异吗? - fatihk
1
我刚刚查看了boost::hash的实现。实际上,除了空字符串(其哈希值为0)之外,根据size_t的大小,你几乎可以保证得到不同的结果。 - James Kanze
显示剩余3条评论
3个回答

5

boost::hash有什么保证?我没有看到生成的哈希码可在生成它的进程之外使用的任何保证。(这通常是哈希函数的情况。)如果您需要一个可用于外部数据的哈希值,可以在不同的程序和平台上有效(例如,对磁盘数据进行哈希访问),那么您将不得不编写自己的哈希函数,如下:

uint32_t
hash( std::string const& key )
{
    uint32_t results = 12345;
    for ( auto current = key.begin(); current != key.end(); ++ current ) {
        results = 127 * results + static_cast<unsigned char>( *current );
    }
    return results;

}

只要不需要移植到一些奇特的大型计算机(可能不支持 uint32_t),

这应该就能解决问题了。


0

上述的哈希函数简单但是弱并且容易受攻击。

例如,将字符串“bb”、“bbbb”、“bbddbb”、“ddffbb”等任意由具有偶数ASCII码的符号组成的组合传递给该函数,并观察低字节。 它总是为57。

相反,我建议使用我的哈希函数,它相对轻量级,且没有容易受攻击的漏洞:

#define NLF(h, c) (rand[(uint8_t)(c ^ h)])
uint32_t rand[0x100] = { 256 random non-equal values };

uint32_t oleg_h(const char *key) {
  uint32_t h = 0x1F351F35;
  char c;
  while(c = *key++)
    h = ((h >> 11) | (h << (32 - 11))) + NLF(h, c);
  h ^= h >> 16;
  return h ^ (h >> 8);
}

0

使用一些著名的通用哈希函数,例如SHA,因为这些函数被认为保证相同的字符串在任何地方具有相同的哈希值。请注意,在进行与安全相关的操作时,SHA可能会过于快速。这是一个奇怪的事情,但有时候快速并不意味着好,因为它会打开暴力攻击的可能性--在这种情况下,有其他更慢的哈希函数,其中一些基本上是将SHA重复多次执行。另外一件事,如果您正在对密码进行哈希处理,请记得给它们加盐(我不会详细介绍,但这些信息可以在网上轻松获取)。


2
既然他问到了boost::hash,我怀疑他并不担心加密安全问题。对于数据访问的哈希处理来说,SHA太慢了,而且它生成的哈希值有足够多的位数,你需要一个大数包才能对其进行模运算,将其缩小到合理范围内。 - James Kanze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接