首页 > 解决方案 > 为什么字符串的哈希值相同?

问题描述

我想计算作为字符串传递的结构的哈希值。尽管vlanId值不同,但哈希值仍然相同。该StringHash()函数计算哈希值。我没有为portIdand赋值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

标签: c++

解决方案


您将结构的字节传递给期望以零结尾的字符串的函数。好吧,您的结构的第一个字节已经为零,因此您每次都计算相同的哈希值。

现在,这就是原因的解释,但不是您问题的解决方案。将随机字节序列传递给期望以零结尾的字符序列的函数将非常失败,无论您如何操作。

找到另一种方法来散列你的结构。您已经在使用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;

推荐阅读