c++ - 为什么字符串的哈希值相同?
问题描述
我想计算作为字符串传递的结构的哈希值。尽管vlanId
值不同,但哈希值仍然相同。该StringHash()
函数计算哈希值。我没有为portId
and赋值vsi
。
#include<stdio.h>
#include <functional>
#include <cstring>
using namespace std;
unsigned long StringHash(unsigned char *Arr)
{
hash<string> str_hash;
string Str((const char *)Arr);
unsigned long str_hash_value = str_hash(Str);
printf("Hash=%lu\n", str_hash_value);
return str_hash_value;
}
typedef struct
{
unsigned char portId;
unsigned short vlanId;
unsigned short vsi;
}VlanConfig;
int main()
{
VlanConfig v1;
memset(&v1,0,sizeof(VlanConfig));
unsigned char *index = (unsigned char *)&v1 + sizeof(unsigned char);
v1.vlanId = 10;
StringHash(index);
StringHash((unsigned char *)&v1);
v1.vlanId = 12;
StringHash(index);
StringHash((unsigned char *)&v1);
return 0;
}
输出:
Hash=6142509188972423790
Hash=6142509188972423790
Hash=6142509188972423790
Hash=6142509188972423790
解决方案
您将结构的字节传递给期望以零结尾的字符串的函数。好吧,您的结构的第一个字节已经为零,因此您每次都计算相同的哈希值。
现在,这就是原因的解释,但不是您问题的解决方案。将随机字节序列传递给期望以零结尾的字符序列的函数将非常失败,无论您如何操作。
找到另一种方法来散列你的结构。您已经在使用hash<>
,为什么不将它用于您的情况:
namespace std
{
template<> struct hash<VlanConfig>
{
std::size_t operator()(VlanConfig const& c) const noexcept
{
std::size_t h1 = std::hash<char>{}(c.portId);
std::size_t h2 = std::hash<short>{}(c.vlanId);
std::size_t h3 = std::hash<short>{}(c.vsi);
return h1 ^ (h2 << 1) ^ (h3 << 2); // or use boost::hash_combine
}
};
}
然后你可以这样做:
VlanConfig myVariable;
// fill myVariable
std::cout << std::hash<VlanConfig>{}(myVariable) << std::endl;