Java中的UTF-16编码与C#

时间:2011-01-25 12:19:44

标签: c# java encoding md5 utf-16

我正在尝试读取UTF-16编码方案中的字符串并对其执行MD5哈希。但奇怪的是,当我尝试这样做时,Java和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

我不确定,为什么输出不一样。我们如何更改上面的代码,以便它们都返回相同的输出?

3 个答案:

答案 0 :(得分:35)

UTF-16!= UTF-16。

在Java中,getBytes("UTF-16")返回一个带有可选字节排序标记的big-endian表示。 C#的System.Text.Encoding.Unicode.GetBytes返回一个小端表示。我无法从这里检查您的代码,但我认为您需要准确指定转换。

在Java版本中尝试getBytes("UTF-16LE")

答案 1 :(得分:5)

我能找到的第一件事,也许这不是唯一的问题,就是C#的Encoding.Unicode.GetBytes()是littleendian,而Java的自然字节顺序是bigendian。

答案 2 :(得分:0)

您可以使用System.Text.Enconding.Unicode.GetString(byte[])从字节转换回字符串。通过这种方式,您可以确保所有操作都采用Unicode编码。