abass.mahdavi
abass.mahdavi

Reputation: 51

C++ hash<string> is there a way to get the same value in Linux and Windows

I'm trying to find a way to get the same result when I hash a given string in Windows and in Linux.

But, for example, if I run the following code:

hash<string> h;
cout << h("hello");

it returns 3305111549 in Windows and 2762169579135187400 in Linux.

If it is not possible to get the same return value across these two platforms, is there any other decent hash function that would return the same value on both systems?

Upvotes: 4

Views: 2313

Answers (4)

Ron
Ron

Reputation: 15521

No. As per std::hash reference, emphasis mine:

The actual hash functions are implementation-dependent and are not required to fulfill any other quality criteria except those specified above.

More specifically you are using the std::hash<std::string> template specialization whose hashes:

equal the hashes of corresponding std::basic_string_view classes

which are also implementation dependent. So no, you can not expect the same std::hash results with different implementations. Furthermore since C++14:

Hash functions are only required to produce the same result for the same input within a single execution of a program;

Upvotes: 4

WhiZTiM
WhiZTiM

Reputation: 21576

I try to find a way to get the same result when I hash a given string in windows and in linux. but for example if I run the following code:

hash<string> h;
cout << h("hello");

it will return 3305111549 in windows and 2762169579135187400 in linux.

The results are correct. As mentioned in other answers, the C++ standard doesn't even guarantee that the values will be the same between various execution of the same program.

If it is not possible to get the same return value accross these 2 platforms, is there any other decent hash function that would return the same value on both systems?

Yes!. You may want to check out Best hashing algorithms for speed and uniqueness for a list of good hash functions to implement.

However, after you select the one you want to use, you need one more extra guarantee: that the underlaying representations of characters are the same between the two platforms. That is that the numerical representations of 'a' in platform 1 is same as 'a' in platform 2. If one platform uses ASCII and the other uses a different encoding scheme, you aren't likely to get the same results.


Again, std::hash<> already has a specialization for std::hash<std::string>. So, other than your standard library's provision, there's nothing you can do about enforcing a behavior for the result of std::hash<std::string>()("hello"). Your option is to use:

  • a custom hash function-object, e.g myNAMESPACE::hash<std::string>()("hello"), or
  • use a custom string type, and specialize it for std::hash; e.g std::hash<MyString>()("hello")

Upvotes: 1

geza
geza

Reputation: 30010

Not only you cannot depend on hash values among different platforms, but the standard doesn't guarantee that the hash value will be the same among different runs of the same program. It only guarantees that the value will be the same during the same run.

This is the only requirement the C++14 standard poses for the returned value (beside that it's type should be std::size_t) (17.6.3.4):

The value returned shall depend only on the argument k for the duration of the program. [ Note: Thus all evaluations of the expression h(k) with the same value for k yield the same result for a given execution of the program. — end note ] [ Note: For two different values t1 and t2, the probability that h(t1) and > h(t2) compare equal should be very small, approaching 1.0 / numeric_limits::max(). — end note ]

(where h is a hash functor, k is the key)

If you want to have the same value, then use a well-known hash algorithm, like MurmurHash3.

Upvotes: 2

Tam&#225;s Zahola
Tam&#225;s Zahola

Reputation: 9311

It won’t work with std::hash:

The actual hash functions are implementation-dependent and are not required to fulfill any other quality criteria except those specified above. 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.

http://en.cppreference.com/w/cpp/utility/hash

Upvotes: 1

Related Questions