使用不同的编译器计算 std::hash

cau*_*chy 6 c++ c++11

我需要在 windows 和 linux 中计算一个大字符串的哈希值,并且两个操作系统的结果应该是相同的。

对于一个简单的测试代码,我使用 std::hash 为 windows 和 linux 获得了不同的哈希值。这是有道理的,因为每个编译器的 std::hash 的实际实现可能使用不同的算法。

这带来了一个问题:有没有办法使用标准库来实现这一目标?

对我来说更直接的答案是实现我自己的哈希算法,所以它对两个操作系统都是一样的。但这似乎有点矫枉过正。我不想重新发明轮子。

Art*_*oul 4

标准库中的哈希算法不是固定的,在不同的平台/编译器上可能会有所不同。

\n

但是您可以使用非常短且快速的 FNV1a 算法进行散列,只需几行代码即可实现功能,请参见下文。你可以在这里读到它。

\n

它会在所有机器上给出相同的结果。但是您必须修复一组参数,32 位或 64 位(32 位参数在我的代码中被注释掉)。

\n

在线尝试一下!

\n
#include <iostream>\n#include <string>\n#include <cstdint>\n\ninline uint64_t fnv1a(std::string const & text) {\n    // 32 bit params\n    // uint32_t constexpr fnv_prime = 16777619U;\n    // uint32_t constexpr fnv_offset_basis = 2166136261U;\n\n    // 64 bit params\n    uint64_t constexpr fnv_prime = 1099511628211ULL;\n    uint64_t constexpr fnv_offset_basis = 14695981039346656037ULL;\n    \n    uint64_t hash = fnv_offset_basis;\n    \n    for(auto c: text) {\n        hash ^= c;\n        hash *= fnv_prime;\n    }\n\n    return hash;\n}\n\nint main() {\n    std::cout << fnv1a("Hello, World!") << std::endl;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
7993990320990026836\n
Run Code Online (Sandbox Code Playgroud)\n

  • @MSalters实际上我认为OP只有字节,所以为了清楚起见,也许在我的代码中最好使用`std::vector&lt;uint8_t&gt;`而不是`std::string`。但是,如果“std::string”内容在所有平台上完全相同,位相同,那么我的算法将给出相同的结果。 (2认同)