Кодировка UTF-16 в Java против C # - PullRequest
11 голосов
/ 25 января 2011

Я пытаюсь прочитать строку в схеме кодирования 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 ]

35 голосов
/ 25 января 2011

UTF-16! = UTF-16.

В Java getBytes("UTF-16") возвращает представление с прямым порядком байтов с необязательной меткой порядка байтов.C # System.Text.Encoding.Unicode.GetBytes возвращает представление с прямым порядком байтов.Я не могу проверить ваш код отсюда, но я думаю, вам нужно точно указать конверсию.

Попробуйте getBytes("UTF-16LE") в версии Java.

5 голосов
/ 25 января 2011

Первое, что я могу найти, и это, возможно, не единственная проблема, это то, что C # Encoding.Unicode.GetBytes () является littleendian, в то время как естественный порядок байтов в Java - bigendian.

0 голосов
/ 25 января 2011

Вы можете использовать System.Text.Enconding.Unicode.GetString(byte[]) для преобразования обратно из байта в строку. Таким образом, вы уверены, что все происходит в кодировке Unicode.

...