我有一个可变大小的二进制数据 blob,可以通过
std::byte
指针和字节大小访问。有没有办法在上面调用std::hash
? (我找不到任何例子)
据我所知,您必须创建一个自定义哈希函数:
#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;
}
可以根据您的用例调整类型。
编辑:我添加了一个替代哈希组合器(已注释掉),理论上可以产生更好的结果。
这是一个基于我的评论的例子:
#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++ 内部使用的)。