c++ - 使用不同的编译器计算 std::hash
问题描述
我需要在 windows 和 linux 中计算一个大字符串的哈希值,两个操作系统的结果应该是一样的。
对于一个简单的测试代码,我使用 std::hash 为 windows 和 linux 获得了不同的哈希值。这是有道理的,因为每个编译器的 std::hash 的实际实现可能使用不同的算法。
这带来了一个问题:有没有办法使用标准库来实现这一点?
对我来说更直接的答案是实现我自己的哈希算法,所以它对于两个操作系统都是一样的。但这似乎是矫枉过正。我不想重新发明轮子。
解决方案
标准库中的哈希算法不是固定的,可能因不同的平台/编译器而异。
但是您可以使用非常短且快速的 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
推荐阅读
- flutter - 只是音频颤振包支持 accADTs 文件格式,因为它在购买的 android 和 iOS 中都支持
- r - 如何在 r 中对同年而不是同月进行分组
- ios - 如何理解 objc 中的 ARC
- php - 在 laravel 中用于多行插入的 insertGetId 的替代方法是什么
- python - 为什么我在使用 urllib.request 时有时会收到“需要 407 身份验证”?
- r - R 的可管道分配函数 - 不分配任何内容
- python - 如何在不需要定义参数的情况下使用 argparse?
- java - RestAssured + Java - 如何保存到字符串或归档发送到服务器的请求?
- tkinter - 在 Tkinter 中扩展 2 个按钮
- python - 提取邮件内容到txt文件