2011-01-25 29 views
11

Tôi đang cố gắng đọc một Chuỗi trong lược đồ mã hóa UTF-16 và thực hiện băm MD5 trên đó. Nhưng kỳ lạ, Java và C# đang trả về các kết quả khác nhau khi tôi cố gắng làm điều đó.Mã hóa UTF-16 trong Java so với C#

Sau đây là đoạn mã trong 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) { 

    } 
} 

Kết quả của việc này là: 249ece65145dca34ed310445758e5504

Sau đây là đoạn mã trong 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); 
     } 

Đầu ra cho điều này là: c04d0f518ba2555977fa1ed7f93ae2b3

Tôi không chắc chắn, tại sao các đầu ra không giống nhau. Làm thế nào để chúng ta thay đổi đoạn mã trên, để cả hai đều trả về cùng một đầu ra?

+0

So sánh các mảng byte của bạn trước tiên. Nếu chúng không phù hợp dù chỉ một chút, thì các băm hoàn toàn khác nhau. Có thể có BOM hoặc bất kỳ điều gì trong mã hóa UTF-16. Nó có thể là nhỏ hoặc lớn endian, hoặc bất cứ điều gì. – maaartinus

Trả lời

35

UTF-16! = UTF-16.

Trong Java, getBytes("UTF-16") trả về một đại diện lớn với dấu thứ tự byte tùy chọn. C# 's System.Text.Encoding.Unicode.GetBytes trả về một đại diện nhỏ. Tôi không thể kiểm tra mã của bạn từ đây, nhưng tôi nghĩ bạn cần xác định chính xác chuyển đổi.

Hãy thử getBytes("UTF-16LE") trong phiên bản Java.

+1

Bạn nói đúng, tôi đã thử nghiệm giải pháp và công trình của bạn. – ehsun7b

+2

Wow !! Cảm ơn nhiều, Luther. Điều này hoạt động như ma thuật. – rkg

+0

Cần lưu ý rằng nếu bạn nhìn vào đầu ra trong nhật thực, nó vẫn không khớp với những gì Visual Studio hiển thị cho bạn. Nhưng kỳ lạ nó hoạt động ... – debracey

5

Điều đầu tiên tôi có thể tìm thấy và điều này có thể không phải là vấn đề duy nhất, đó là Encoding.Unicode.GetBytes() của C# là nhỏ, trong khi thứ tự byte của Java là bigendian.

0

Bạn có thể sử dụng System.Text.Enconding.Unicode.GetString(byte[]) để chuyển đổi từ byte thành chuỗi. Bằng cách này, bạn chắc chắn rằng tất cả xảy ra trong mã hóa Unicode.

Các vấn đề liên quan