2016-06-26 35 views
3

に基づいて一意のハッシュコードを生成します。一見は、私は、次の2つの文字列持つ文字列

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"; 

をこれら2つの文字列がしかし、彼らのハッシュコードは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になります。よりユニークなハッシュコードを返す別のメソッドがありますか?文字列の文字に基づいて一意になるようにhashcodeが必要です。両方の文字列が異なっていて、コードが適切に動作していますが、これらの2つの文字列は同じようになります。このコードをよりユニークにするためにこのコードを改善するにはどうすればよいですか?

+2

可能なすべての文字列に対してユニークなハッシュコードを保証することはできません。ハッシュコードは32ビットであり、可能な値は40億(および変更可能)です。あなたの2つの文字列はそれぞれ120文字以上です。 96文字の印刷可能なASCII文字を使用する可能性のある120文字の文字列の数は、はるかに多くなります。衝突は避けられない。 *一般的なケースでは一意のハッシュコード*は存在しません。ハッシュコードを大きくすると衝突の可能性は低くなりますが、ハッシュコードを排除することはできません。 –

+2

あなたの質問は、あなたが一意の識別子としてハッシュコードを使用しようとしていることを意味しています。これは信じられないほど悪い考えであり、失敗することになります。 @AlexDの答えがなぜその理由を説明します。 –

+0

@JimMischelはい私はこれを今気付いていますが、ありがとう –

答えて

12

string.GetHashCodeは確かに実際のハッシュのために不適切である:ハッシュコードはハッシュテーブルに基づいてコレクションに効率的挿入およびルックアップのために意図されて

警告。ハッシュコードは永続的な値ではありません。このため、

  • ハッシュコード値をシリアル化したり、データベースに格納したりしないでください。
  • キー付きコレクションからオブジェクトを取得するためのキーとしてハッシュコードを使用しないでください。
  • 暗号化ハッシュ関数によって返された値の代わりにハッシュコードを使用しないでください。暗号化ハッシュの場合は、System.Security.Cryptography.HashAlgorithmまたはSystem.Security.Cryptography.KeyedHashAlgorithmクラスから派生したクラスを使用します。
  • ハッシュコードが等しいかどうかをテストして、2つのオブジェクトが等しいかどうかを判断しないでください。等しくないかどうかをテストするには、ReferenceEqualsまたはEqualsメソッドを呼び出します。

であり、duplicatesの可能性が高い。

HashAlgorithm.ComputeHashを考えてください。

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(); 
} 
+0

の完全な例については、https://msdn.microsoft.com/en-us/library/system.security.cryptography.md5(v=vs.110).aspx – lexx9999

+0

@ lexx9999を参照してください。すでに同じアルゴリズムです。 – AlexD

+0

私はそれを読んでいたので、GetMd5Hash/VerifyMd5H​​ashは含まれていません – lexx9999

1
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; 
} 

ハッシュが順番にあなたには、いくつかの進文字列またはBASE64エンコードにひそか可能性が16バイト配列、次のとおりです。@zaphが示唆したようにサンプルはわずか、SHA256の代わりにMD5のを使用するように変更されます保存用の文字列。

編集:

そのハッシュコードの目的は何ですか?ハッシュから

(X)!=ハッシュ(Y)あなたは、xを導き出すことができます!= Yが、ハッシュから

(X)==ハッシュ(y)を使用すると、は、一般的には、X == yのを導き出すことはできません

+0

これによりパフォーマンスが低下し、セキュリティハッシュが衝突を回避するために使用されるわけではありません。 –

+0

@ lexx9999ハッシュコードの目的は重複と区別することです。文字列はWebスクレーパーから返されます。私は私の質問で一例として使用する2つの文字列のためのあなたの提案されたコードを試してきましたが、私はまだ全体のプログラムでこれを試しても私は重複を取得しようとします。 –

+1

@somerandomdude、すべてのハッシュ関数と同じように、元のデータを比較する必要があります。他のハッシュアルゴリズムを試すこともできますが、必ず衝突を予想する必要があります。それは、 'hash(x)== hash(y)から、一般にx == yを導くことはできません! 'という意味です。 – lexx9999

関連する問題