Get 32-bit hash value from boost::hash

后端 未结 3 1808
感动是毒
感动是毒 2021-02-16 00:29

I am using boost::hash to get hash value for a string. But it is giving different hash values for same string on Windows 32-bit and Debian 64-bit systems.

S

相关标签:
3条回答
  • 2021-02-16 01:05

    Hash-function above is simple, but weak and vulnerable.

    For example, pass to that function string like "bb" "bbbb" "bbddbb" "ddffbb" -- any combination of pairs symbols with even ASCII codes, and watch for low byte. It always will be 57.

    Rather, I recommend to use my hash function, which is relative lightweight, and does not have easy vulnerabilities:

    #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 讨论(0)
  • 2021-02-16 01:06

    Use some of the well-known universal hash functions such as SHA instead, because those are supposed to guarantee that the same string will have the same hash everywhere. Note that in case you are doing something security-related, SHA might be too fast. It's a strange thing to say, but sometimes fast does not mean good as it opens a possibility for a brute force attack - in this case, there are other, slower hash function, some of which basically re-apply SHA many times in a row. Another thing, if you are hashing passwords, remember to salt them (I won't go into details, but the information is readily accessible online).

    0 讨论(0)
  • 2021-02-16 01:17

    What is the guarantee concerning boost::hash? I don't see any guarantees that a generated hash code is usable outside of the process which generates it. (This is frequently the case with hash functions.) If you need a hash value for external data, valid over different programs and different platforms (e.g. for a hashed access to data on disk), then you'll have to write your own. Something like:

    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;
    
    }
    

    should do the trick, as long as you don't have to worry about porting to some exotic mainframes (which might not support uint32_t).

    0 讨论(0)
提交回复
热议问题