从 6 字节字段计算哈希
Calculating a hash from a 6-byte field?
我正在寻找一种有效的方法来散列 6 字节字段,以便它可以用于std::unordered_map
。
我认为这将是创建哈希的传统方式:
struct Hash {
std::size_t operator()(const std::array<uint8_t, 6> & mac) const {
std::size_t key = 0;
boost::hash_combine(key, mac[0]);
boost::hash_combine(key, mac[1]);
boost::hash_combine(key, mac[2]);
boost::hash_combine(key, mac[3]);
boost::hash_combine(key, mac[4]);
boost::hash_combine(key, mac[5]);
return key;
}
};
但是我注意到我可以使用这个技巧让它更快一点(~20%(:
struct Hash {
std::size_t operator()(const std::array<uint8_t, 6> & mac) const {
std::size_t key = 0;
// Possibly UB?
boost::hash_combine(key, reinterpret_cast<const uint32_t&>(mac[0]));
boost::hash_combine(key, reinterpret_cast<const uint16_t&>(mac[4]));
return key;
}
};
这甚至更快:
struct Hash {
std::size_t operator()(const std::array<uint8_t, 6> & mac) const {
// Requires size_t to be 64-bit.
static_assert(sizeof(std::size_t) >= 6, "MAC address doesn't fit in std::size_t!");
std::size_t key = 0;
// Likely UB?
boost::hash_combine(key, 0x0000FFFFFFFFFFFF & reinterpret_cast<const uint64_t&>(mac[0]));
return key;
}
};
我的问题是双重的:
- 这些优化会导致 UB 吗?
- 我的第一个解决方案是要走的路吗?还是有更好的方法?
您的优化正在打破严格的别名规则,这会导致(标准地说(未定义的行为。
最后一个优化最让我担心,因为您本质上是在读取不应该读取的内存,如果此内存恰好受到保护,这可能会引发陷阱。
您不使用boost::hash_range
的任何原因?
由于事实证明boost::hash_range
没有所需的那么快,因此我会提出另一种基于混叠的解决方案。或者更确切地说,两种解决方案合二为一。
第一个想法是可以使用char*
作为临时类型来抑制别名。
size_t key = 0;
char* k = &reinterpret_cast<char*>(&key);
std::copy(mac.begin(), mac.end(), k);
return key;
因此,是哈希的有效实现。
但是,我们可以更进一步。由于对齐和填充,存储char[6]
和char[8]
可能会在映射节点中使用相同数量的内存。因此,我们可以通过使用union
来丰富类型:
union MacType {
unsigned char value[8];
size_t hash;
};
现在,您可以将其正确封装在类中(并确保始终初始化字节7
并8
0
(,并实现您实际需要的std::array<unsigned char, 6>
接口。
我对小字符串(低于 8 个字符(使用了类似的技巧进行哈希和快速(非字母(比较,这真的很甜蜜。
相关文章:
- 使用Qt C++计算类似Git的SHA1哈希
- 如何计算结构的哈希
- 在Javascript和C++中计算MD5哈希的不同结果
- 如何在 64 位平台上计算 32 位哈希C++?
- C++ 提升哈希计算而不会发生冲突
- 如何在 c++ 中计算对象的哈希/校验和/指纹?
- 如果我放弃哈希计算,我必须调用 SHA1_Final() 吗?
- 哈希函数计算
- 计算地图结构的哈希
- std::unordered_map 的哈希代码是如何计算的
- C++ 如何在使用哈希函数时计算冲突次数
- 在C++中是否已经为文件系统迷你过滤器驱动程序编写了一个计算MD5哈希的函数
- 如何计算没有标签信息的 mp3 文件的哈希值
- 如何在C++中可移植地计算sha1哈希
- C++中的SHA256哈希计算
- 从 6 字节字段计算哈希
- 可以改进哈希以计算频率
- 如何在C++中准确地计算lops示例:计算哈希
- 计算哈希插入的运行时间
- 如何计算哈希表中碰撞的次数?