2011-01-25 9 views
11

私はUTF-16エンコーディングスキームで文字列を読み込み、その上でMD5ハッシュを実行しようとしています。しかし、不思議なことに、JavaとC#は私がそれをやろうとすると、別の結果を返しています。JavaのUTF-16エンコーディングとC#

は、以下のJavaにおけるコードの一部である:

public static void main(String[] args) { 
    String str = "preparar mantecado con coca cola"; 
    try { 
     MessageDigest digest = MessageDigest.getInstance("MD5"); 
     digest.update(str.getBytes("UTF-16")); 
     byte[] hash = digest.digest(); 
     String output = ""; 
     for(byte b: hash){ 
      output += Integer.toString((b & 0xff) + 0x100, 16).substring(1); 
     } 
     System.out.println(output); 
    } catch (Exception e) { 

    } 
} 

このため出力は:

249ece65145dca34ed310445758e5504

C#におけるコードの一部であります

public static string GetMD5Hash() 
     { 
      string input = "preparar mantecado con coca cola"; 
      System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider(); 
      byte[] bs = System.Text.Encoding.Unicode.GetBytes(input); 
      bs = x.ComputeHash(bs); 
      System.Text.StringBuilder s = new System.Text.StringBuilder(); 
      foreach (byte b in bs) 
      { 
       s.Append(b.ToString("x2").ToLower()); 
      } 
      string output= s.ToString(); 
      Console.WriteLine(output); 
     } 

この出力は次のとおりです。c04d0f518ba2555977fa1ed7f93ae2b3

出力が同じでない理由はわかりません。上記のコードをどのように変更すれば、両方とも同じ出力を返すことができますか?

+0

まず、バイト配列を比較してください。 1ビットでも不一致の場合、ハッシュは完全に異なります。 UTF-16エンコーディングにはBOMなどがあります。少しでも大きなエンディアンでも、何でもかまいません。 – maaartinus

答えて

35

UTF-16!= UTF-16。

Javaでは、getBytes("UTF-16")は、オプションのバイトオーダーマーク付きのビッグエンディアン表現を返します。 C#のSystem.Text.Encoding.Unicode.GetBytesは、リトルエンディアン表現を返します。ここからコードを確認することはできませんが、変換を正確に指定する必要があると思います。

getBytes("UTF-16LE")をJavaバージョンで試してください。

+1

あなたが正しいです、私はあなたのソリューションと作品をテストしました。 – ehsun7b

+2

うわー!!ありがとう、ルーサー。これは魔法のように機能します。 – rkg

+0

eclipseで出力を見ると、それでもVisual Studioに表示されているものと一致しないことに注意してください。しかし、不思議なことにそれは動作します... – debracey

5

C#のEncoding.Unicode.GetBytes()はリトルエンディアンであり、Javaの自然なバイトオーダーはbigendianですが、これが唯一の問題ではないことがあります。

0

System.Text.Enconding.Unicode.GetString(byte[])を使用して、バイトから文字列に変換することができます。このようにして、すべてがUnicodeエンコードで行われることが確実です。