2009-03-08 9 views
1

私のテキストファイルは、茶色の狐が怠惰な犬の上を飛びます。しかし、このファイルからハッシュを取得しようとすると、md5とsha1の両方がwikipediasの結果と異なっています。私には3つの質問があります。 1)コードで何が間違っていたのですか? 2)どのようにしてこのコードを改善できますか? (私は初期化が必要ですか?)3)どうやってこれを塩にしますか?私は間違ったハッシュ値を持っていますか? C#の暗号化

{ 
     const int bufSize = 1024 * 8; 
     int read; 
     byte[] buf = new byte[bufSize]; 
     string fn = @"b.txt"; 
     byte[] result1 = new byte[0]; 
     byte[] result2 = new byte[0]; 
     SHA1 sha = new SHA1CryptoServiceProvider(); 
     MD5 md5 = new MD5CryptoServiceProvider(); 
     sha.Initialize(); 
     md5.Initialize(); 
     FileStream fin = File.OpenRead(fn); 
     while ((read = fin.Read(buf, 0, buf.Length)) != 0) 
     { 
      result1 = sha.ComputeHash(buf); 
      result2 = md5.ComputeHash(buf); 
     } 
     fin.Close(); 
     MessageBox.Show(myFunc(result1)); 
     MessageBox.Show(myFunc(result2)); 
    } 

答えて

6

は(EDIT:私はそれは不要だ疑いがあるが、それは良い習慣だ:)

あなたはあなただけの部分をハッシュする必要があるにもかかわらず、全体バッファ用のComputeHashを呼び出している今、ハッシュアルゴリズムの廃棄あなたが読んだバッファ。さらに、Readの呼び出しごとに新しいハッシュを計算しています。

はここでハッシュを計算するために、いくつかの本当に簡単なコードです:

using System; 
using System.IO; 
using System.Security.Cryptography; 

class Test 
{ 
    static void Main() 
    { 
     byte[] plaintext = File.ReadAllBytes("b.txt"); 
     using (MD5 md5 = MD5.Create()) 
     { 
      byte[] md5Hash = md5.ComputeHash(plaintext); 
      Console.WriteLine(BitConverter.ToString(md5Hash)); 
     } 

     using (SHA1 sha1 = SHA1.Create()) 
     { 
      byte[] sha1Hash = sha1.ComputeHash(plaintext); 
      Console.WriteLine(BitConverter.ToString(sha1Hash)); 
     } 
    } 
} 

これは、ウィキペディアごとに結果を与える - b.txtはそれの終わりに改行を持つべきではないことに注意してください。

で開始するバイナリデータを取得する別の方法は次のようになります。これはただ一度にハッシュを計算する簡単な方法であることを

byte[] plaintext = Encoding.ASCII.GetBytes(
    "The quick brown fox jumps over the lazy dog"); 

注意。あなたがストリーミング方法でそれをやりたい場合(つまり、データを読み込んだりハッシュに追加したり、もっと多くのデータを読み込んだりするなど)、ComputeHash(Stream)オーバーロードを使うこともできますし(データをそこにプッシュする我々はすべての出力を必要としない、と我々は最終ブロック内のすべてのデータを変換していないので、我々はTransformBlocknullを渡す方法に注意してください

using System.Text; 

class Test 
{ 
    static void Main() 
    { 
     using (MD5 md5 = MD5.Create()) 
     using (SHA1 sha1 = SHA1.Create()) 
     using (Stream input = File.OpenRead("b.txt")) 
     { 
      // Artificially small to make sure there's 
      // more than one read 
      byte[] buffer = new byte[4]; 
      int bytesRead; 

      while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       md5.TransformBlock(buffer, 0, bytesRead, null, 0); 
       sha1.TransformBlock(buffer, 0, bytesRead, null, 0); 
      } 
      md5.TransformFinalBlock(buffer, 0, 0); 
      sha1.TransformFinalBlock(buffer, 0, 0); 

      Console.WriteLine(BitConverter.ToString(md5.Hash)); 
      Console.WriteLine(BitConverter.ToString(sha1.Hash)); 
     } 
    } 
} 

:)あなたはこのように、TransformBlockTransformFinalBlockを使用することができます。私はあなたの前のコメントに基づいて、これがあなたが使いたいと思う例だと思っています。

+0

奇妙なケースで私のファイルが複数のgbになる可能性があるので、ストリーミング形式で読む必要があります。この例は、私がウィキペディアで同じハッシュの言葉を持っているかどうかを確認することだけでした。 ストリーミングの部分は難しいですが、ComputeHashは現在のハッシュ値を伝えることができないようです。 –

+0

@acidzombie:私の編集を参照してください - 私はあなたが与えた2番目の例がほしいと思います。 –

+0

パーフェクト、完璧。それは素晴らしい作品、ありがとう:D –

0

これらのハッシュアルゴリズムはバイトを処理するため、異なる結果については、テキストで使用している文字エンコーディングによって異なる場合があります。

あなたのコードを改善する限り、あなたはCryptoServiceProvidersを処分していません。 HashAlgorithmから継承するものはすべてIDisposableを実装しており、終了時にはusing()を使用するか、直接Dispose()を呼び出して処理する必要があります。また、IDisposableに関する要件が同じFileStreamを処分していないこともあります。

+0

私はすべての文字エンコーディング(少なくともLatingアルファベットを扱うものすべて)は文字列「茶色のキツネが怠惰な犬の上をジャンプする」を同じバイトセットにマッピングすると考えています。 –

+1

@David:Encoding.Unicode.GetBytes(「茶色のキツネが怠惰な犬の上を飛ぶ」)またはEncoding.UTF32.GetBytes()を試してください。 –

関連する問題