首页 > 解决方案 > 使用不同的编译器计算 std::hash

问题描述

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

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

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

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

标签: c++c++11

解决方案


标准库中的哈希算法不是固定的,可能因不同的平台/编译器而异。

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

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

在线尝试!

#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;
}

输出:

7993990320990026836

推荐阅读