I learn from this problem that the default hash function used in std::unordered_map
is murmurhash2.
// This file defines Hash_bytes, a primitive used for defining hash
// functions. Based on public domain MurmurHashUnaligned2, by Austin
// Appleby. http://murmurhash.googlepages.com/
My problem is how can I change the default seed of that hash function, as a constant hash seed is prone to be hacked.
p.s. I know I can use my own hash factor with unordered_map
. But my question is about the seed of builtin hash function of C++11.
The third template argument of std::unordered_map
is the hash functor to be used, which can be set to whatever hash function you want.
Note that, according to Wikipedia, MurmurHash (https://en.wikipedia.org/wiki/MurmurHash) is a non-cryptographic hash function, thus not suited if strong cryptography is needed.
However, in a std::unordered_map
, the hash is not used for security reasons but to organize the key/value pairs into buckets of memory. Moreover, for example in gcc, basic types are not hashed at all, but reinterpret_cast<size_t>
to size_t
. From http://en.cppreference.com/w/cpp/utility/hash :
Notably, some implementations use trivial (identity) hash functions which map an integer to itself. In other words, these hash functions are designed to work with unordered associative containers, but not as cryptographic hashes, for example.
If you nevertheless want to change the seed of the hash, you need to implement a functor object and provide your own hash algorithm. The code below should give you an idea how to hook in your own hash implementation or how to directly use MurmurHash2 and provide a seed.
The line indicated with //HACK
will use the hash function from the gcc library implementation (std::_Hash_impl::hash
) and will depend on a particular compiler/library implementation. As others pointed out, direct use of this function is discouraged.
If other types than std::string
need to be hashed, different template specializations need to be implemented.
#include <string>
#include <unordered_map>
#include "MurmurHash2.h"
template <class T> struct MyHash;
template<> struct MyHash<std::string>
{
std::size_t operator()(std::string const& s) const noexcept
{
size_t seed = static_cast<size_t>(0xdeadbeef);
//return std::_Hash_impl::hash(s.data(), s.length(), seed); //HACK
return MurmurHash2 ( s.data(), s.length(), seed );
}
};
int main()
{
std::unordered_map<std::string,std::string,MyHash<std::string> >
u_map { {"s1","A"} , {"s2","B"} };
return 0;
};
Get MurmurHash from github.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With