如何更改 std::hash<> 中的默认种子?

How can I change the default seed in std::hash<>?

本文关键字:种子 默认 lt 何更改 std hash gt      更新时间:2023-10-16

我从这个问题中了解到,std::unordered_map中使用的默认哈希函数是murmurhash2。

// This file defines Hash_bytes, a primitive used for defining hash
// functions. Based on public domain MurmurHashUnaligned2, by Austin
// Appleby.  http://murmurhash.googlepages.com/

我的问题是我如何更改该哈希函数的默认种子,因为常量哈希种子很容易被黑客入侵。

附言我知道我可以将自己的哈希函子与 unordered_map 一起使用。但我的问题是关于 C++11 内置哈希函数的种子。

请注意

,根据维基百科,MurmurHash(https://en.wikipedia.org/wiki/MurmurHash)是一个非加密哈希函数,因此不适合需要强加密。

然而,在std::unordered_map中,哈希不是出于安全原因,而是用于将键/值对组织到内存桶中。此外,例如在 gcc 中,基本类型根本不是散列的,而是reinterpret_cast<size_t> size_t .从 http://en.cppreference.com/w/cpp/utility/hash :

值得注意的是,一些实现使用简单的(身份)哈希函数 将整数映射到自身。换句话说,这些哈希函数 设计为与无序关联容器一起使用,但不能作为 例如,加密哈希。

如果您仍然想更改哈希的种子,则需要实现一个函子对象并提供您自己的哈希算法。下面的代码应该让你了解如何挂钩自己的哈希实现,或者如何直接使用 MurmurHash2 并提供种子。

//HACK表示的行将使用来自gcc库实现(std::_Hash_impl::hash)的哈希函数,并将取决于特定的编译器/库实现。正如其他人指出的那样,不鼓励直接使用此功能。

如果需要对除std::string以外的其他类型进行哈希处理,则需要实现不同的模板专用化。

#include <string>
#include <unordered_map>
#include "MurmurHash2.h"
template <class T> struct MyHash;
template<> struct MyHash<std::string>
{
    std::size_t operator()(std::string const& s) const noexcept
    {
        size_t seed = static_cast<size_t>(0xdeadbeef);
        //return std::_Hash_impl::hash(s.data(), s.length(), seed); //HACK
        return MurmurHash2 ( s.data(), s.length(), seed );
    }
};

int main()
{
    std::unordered_map<std::string,std::string,MyHash<std::string> >
            u_map { {"s1","A"} , {"s2","B"} };
    return 0;
};

从github获取MurmurHash。

std::unordered_map的第三个模板参数是要使用的哈希函子,可以设置为您想要的任何哈希函数。