std::hash 带指针和字节大小

问题描述 投票:0回答:2

我有一个可变大小的二进制数据 blob,可以通过

std::byte
指针和字节大小访问。有没有办法在上面调用
std::hash
? (我找不到任何例子)

c++ hash stdhash
2个回答
1
投票

据我所知,您必须创建一个自定义哈希函数:

#include <algorithm>
#include <array>
#include <iostream>
#include <vector>

template<class T, size_t N>
struct std::hash<std::array<T, N>> {
    std::size_t operator()(const std::array<T, N>& data) const noexcept {
        std::size_t value = data.size();
        for (auto byte : data) {
            value = std::hash<std::byte>{}(byte) + (value << 6) + (value >> 2);
            // value = value * 31 + std::hash<std::byte>{}(byte);
        }
        return value;
    }
};

int main(int argc, const char *argv[]) {

    std::array<std::byte, 4> bytes{std::byte{0}, std::byte{1}, std::byte{2}, std::byte{3}};
    auto n = std::hash<std::array<std::byte, 4>>{}(bytes);
    std::cout << n << std::endl;

    return 0;
}

可以根据您的用例调整类型。

编辑:我添加了一个替代哈希组合器(已注释掉),理论上可以产生更好的结果。


0
投票

这是一个基于我的评论的例子:

#include <span>
#include <iostream>
#include <string_view>

using bytes = std::span<const std::byte>;

template <>
struct std::hash<bytes>
{
    std::size_t operator()(const bytes& x) const noexcept
    {
        return std::hash<std::string_view>{}({reinterpret_cast<const char*>(x.data()), x.size()});
    }
};

int main()
{
    auto integers = std::array { 1, 2, 3, 4, 5 };
    auto doubles = std::array { 1.2, 3.4, 5.6, 7.8, 9.0 };
    std::string string = "A string";
    
    auto hash = std::hash<bytes>{};

    std::cout << std::hex;
    std::cout << hash(std::as_bytes(std::span(integers))) << "\n";
    std::cout << hash(std::as_bytes(std::span(doubles))) << "\n";
    std::cout << hash(std::as_bytes(std::span(string))) << "\n";
}

当然,我用的是

std::span
,但你可以使用其他任何东西(例如
std::pair<const std::byte*, std::size_t>
)。

或者,您可以使用 MurmurHash(我相信这就是 libstdc++ 内部使用的)。

© www.soinside.com 2019 - 2024. All rights reserved.