I need to calculate the hash of a large string in windows and linux, and the result should be the same for both OS.
For a simple test code, I get different hashes for windows and linux using std::hash. This makes sense, since the actual implementation of std::hash for each compiler might use different algorithms.
Which brings the question: Is there a way to achieve this using the standard library?
The more straight forward answer for me is to implement my own hash algorithm, so its the same for both OS. But this seems like an overkill. I don't want to reinvent the wheel.
In standard library hash algorithm is not fixed, may vary on different platforms/compilers.
But you can use very short and fast FNV1a algorithm for hashing, function with few lines of code, see below. You can read about it here.
It will give same result on all machines. But you have to fix set of params, 32-bit or 64-bit (32-bit params are commented out in my code).
Try it online!
#include <iostream>
#include <string>
#include <cstdint>
inline uint64_t fnv1a(std::string const & text) {
// 32 bit params
// uint32_t constexpr fnv_prime = 16777619U;
// uint32_t constexpr fnv_offset_basis = 2166136261U;
// 64 bit params
uint64_t constexpr fnv_prime = 1099511628211ULL;
uint64_t constexpr fnv_offset_basis = 14695981039346656037ULL;
uint64_t hash = fnv_offset_basis;
for(auto c: text) {
hash ^= c;
hash *= fnv_prime;
}
return hash;
}
int main() {
std::cout << fnv1a("Hello, World!") << std::endl;
}
Output:
7993990320990026836
Is there a way to achieve this using the standard library?
No, not only using the standard library since the hash algorithm used is not standardized.
I don't want to reinvent the wheel.
Unfortunately, you would have to.
You could however try to get rid of the requirement that they should be the same. If you can't compare the data after a hash hit, you wouldn't be sure that you got a true hit anyway.
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