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.