基于String生成唯一的哈希代码

时间:2016-06-26 22:57:40

标签: c#

我有以下两个字符串:

var string1 = "MHH2016-05-20MASTECH HOLDINGS, INC. Financialshttp://finance.yahoo.com/q/is?s=mhhEDGAR Online FinancialsHeadlines";

var string2 = "CVEO2016-06-22Civeo upgraded by Scotia Howard Weilhttp://finance.yahoo.com/q/ud?s=CVEOBriefing.comHeadlines";

乍一看这两个字符串是不同的,但是使用GetHashCode method它们的哈希码是相同的。

        var hash = 0;
        var total = 0;
        foreach (var x in string1) //string2
        {
            //hash = x * 7;
            hash = x.GetHashCode();
            Console.WriteLine("Char: " +  x + " hash: " + hash + " hashed: " + (int) x);
            total += hash;
        }

两个字符串的总计最终为620438779。还有另一种方法会返回更独特的哈希码吗?我需要基于字符串中的字符使哈希码唯一。尽管两个字符串都不同并且代码正常工作,但这两个字符串恰好相同。如何改进此代码以使其更独特?

2 个答案:

答案 0 :(得分:22)

string.GetHashCode确实不适合真正的哈希:

  

警告

     

哈希代码用于在基于哈希表的集合中进行有效插入和查找。哈希码不是永久值。出于这个原因:

     
      
  • 不要序列化哈希码值或将它们存储在数据库中。
  •   
  • 请勿使用哈希码作为密钥从密钥集合中检索对象。
  •   
  • 不要使用哈希码而不是加密哈希函数返回的值。对于加密哈希,请使用从System.Security.Cryptography.HashAlgorithmSystem.Security.Cryptography.KeyedHashAlgorithm类派生的类。
  •   
  • 不测试哈希码的相等性以确定两个对象是否相等。 (不相等的对象可以具有相同的哈希码。)要测试相等性,请调用ReferenceEqualsEquals方法。
  •   

并且duplicates的可能性很高。

考虑HashAlgorithm.ComputeHash。稍微更改了样本以使用SHA256而不是MD5,因为建议 @zaph

static string GetSha256Hash(SHA256 shaHash, string input)
{
    // Convert the input string to a byte array and compute the hash.
    byte[] data = shaHash.ComputeHash(Encoding.UTF8.GetBytes(input));

    // Create a new Stringbuilder to collect the bytes
    // and create a string.
    StringBuilder sBuilder = new StringBuilder();

    // Loop through each byte of the hashed data 
    // and format each one as a hexadecimal string.
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString("x2"));
    }

    // Return the hexadecimal string.
    return sBuilder.ToString();
}

答案 1 :(得分:3)

using System.Security.Cryptography;
string data="test";
byte[] hash;
using (MD5 md5 = MD5.Create())
{
    md5.Initialize();
    md5.ComputeHash(Encoding.UTF8.GetBytes(data));
    hash = md5.Hash;
}

hash是一个16字节的数组,反过来你可以转换为一些hex-string或base64编码的字符串进行存储。

编辑:

哈希码的目的是什么?

从hash(x)!= hash(y)你可以导出x!= y,但是

来自hash(x)== hash(y)你一般不能派生x == y!