Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating std::hash using different compilers

Tags:

c++

c++11

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.

like image 567
cauchi Avatar asked Mar 23 '21 13:03

cauchi


2 Answers

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
like image 103
Arty Avatar answered Oct 22 '22 06:10

Arty


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.

like image 40
Ted Lyngmo Avatar answered Oct 22 '22 06:10

Ted Lyngmo