I am trying to hash single std::string
and std::vector<std::string>
values. I am following the examples from cppreference and boost. When the code is compiled and run on Windows vs Linux, I get different results.
The header file for MyHasher.h
is as follows.
class MyHasher {
private:
MyHasher() = delete;
public:
static std::size_t hash(std::vector<std::string> ids);
static std::size_t hash(std::string s);
static void hashCombine(std::size_t &seed, std::size_t value);
};
The CPP file MyHasher.cpp
is as follows.
std::size_t MyHasher::hash(std::vector<std::string> ids) {
std::size_t seed = 0;
for (auto id : ids) {
std::size_t h = std::hash<std::string>{}(id);
hashCombine(seed, h);
}
return seed;
}
std::size_t MyHasher::hash(std::string s) {
std::size_t seed = 0;
std::size_t h = std::hash<std::string>{}(s);
hashCombine(seed, h);
return seed;
}
void MyHasher::hashCombine(std::size_t &seed, std::size_t value) {
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
A sample program then runs as follows.
int main() {
std::cout << std::to_string(MyHasher::hash("0")) << " | 0" << std::endl;
std::cout << std::to_string(MyHasher::hash(std::vector<std::string>{"0"})) << " | 0" << std::endl;
std::cout << std::to_string(MyHasher::hash(std::vector<std::string>{"0", "1"})) << " | 0 1" << std::endl;
return 0;
}
On Linux (g++ 7.4.0), the output is as follows.
2297668036269395695 | 0 2297668036269395695 | 0 10545066640295778616 | 0 1
On Windows (Visual Studio Community 2019, MSVC-14.0), the output is as follows.
12638135526163551848 | 0 12638135526163551848 | 0 1964774108746342951 | 0 1
Any ideas on this discrepancy?
What I really want is a way to always produce an unique hash output that is dependent on the input, but cross-platform and fixed width. The width is not important, per say, but as long as it is the same width regardless of the input(s).