我有以下两个字符串:
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。还有另一种方法会返回更独特的哈希码吗?我需要基于字符串中的字符使哈希码唯一。尽管两个字符串都不同并且代码正常工作,但这两个字符串恰好相同。如何改进此代码以使其更独特?
答案 0 :(得分:22)
string.GetHashCode
确实不适合真正的哈希:
警告强>
哈希代码用于在基于哈希表的集合中进行有效插入和查找。哈希码不是永久值。出于这个原因:
- 不要序列化哈希码值或将它们存储在数据库中。
- 请勿使用哈希码作为密钥从密钥集合中检索对象。
- 不要使用哈希码而不是加密哈希函数返回的值。对于加密哈希,请使用从
System.Security.Cryptography.HashAlgorithm
或System.Security.Cryptography.KeyedHashAlgorithm
类派生的类。- 不测试哈希码的相等性以确定两个对象是否相等。 (不相等的对象可以具有相同的哈希码。)要测试相等性,请调用
ReferenceEquals
或Equals
方法。
并且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!