1

我在这里的理解显然有一些不完整的地方。如果我运行下面的代码,我希望看到:

 translateTest:: start
  start_korean: (6)  c0 af c8 f1 c8 c6
 expected_utf8: (6)  c7 20 d7 6c d6 c8
    found_utf8: (6)  c7 20 d7 6c d6 c8
 expected utf8 matches found? true

我得到的是:

 translateTest:: start
  start_korean: (6)  c0 af c8 f1 c8 c6
 expected_utf8: (6)  c7 20 d7 6c d6 c8
    found_utf8: (9)  ec 9c a0 ed 9d ac ed 9b 88
 expected utf8 matches found? false

我认为创建字符串,将字节声明为 x-windows-949,然后将字节获取为 utf-8 会将它们从一个转换为另一个。显然,我对此并不正确。

public class translateTest {

  public static void main (String [] Argv) {
      (new translateTest()).translate();
  }

  void translate() {
    System.out.println("translateTest:: start");

    try {

      // pages below linked from http://msdn.microsoft.com/en-US/goglobal/cc305154

      // Please ignore the lame bytesToHex helper method. Including it for completeness.

      // from http://msdn.microsoft.com/en-US/goglobal/gg696909
      //
      // 0xC0AF =  U+C720 = HANGUL SYLLABLE IEUNG YU

      // from http://msdn.microsoft.com/en-US/goglobal/gg696960
      //
      // 0xC8F1 =  U+D76C = HANGUL SYLLABLE HIEUH YI

      // also from http://msdn.microsoft.com/en-US/goglobal/gg696960
      //
      // 0xC8C6 =  U+D6C8 = HANGUL SYLLABLE HIEUH U NIEUN

      byte[] start_korean = new byte[] { (byte)0xC0, (byte)0xAF, (byte)0xC8, (byte)0xF1, (byte)0xC8, (byte)0xC6 };
      byte[] expected_utf8 = new byte[] { (byte)0xC7, (byte)0x20, (byte)0xD7, (byte)0x6C, (byte)0xD6, (byte)0xC8 };
      String str = new String(start_korean, "x-windows-949");
      byte[] found_utf8 = str.getBytes("utf8");

      boolean isEqual = java.util.Arrays.equals(expected_utf8, found_utf8);

      System.out.println(" start_korean: "+bytesToHex(start_korean));
      System.out.println("expected_utf8: "+bytesToHex(expected_utf8));
      System.out.println("   found_utf8: "+bytesToHex(found_utf8));

      System.out.println("expected utf8 matches found? "+isEqual);

    } catch (java.io.UnsupportedEncodingException uee) {
      System.err.println(uee.getMessage());
    }
  }

  public static String bytesToHex(byte[] b) {
    StringBuffer str = new StringBuffer("("+b.length+") ");
    for (int idx = 0; idx < b.length; idx++) {
      str.append(" "+byteToHex(b[idx]));
    }
    return str.toString();
  }

  public static String byteToHex(byte b) {
    String hex = Integer.toHexString(b);
    while (hex.length() < 2) hex = "0"+hex;
    if (hex.length() > 2)
      hex = hex.substring(hex.length()-2);
    return hex;
  }
}
4

2 回答 2

2

您的问题是您的“预期 UTF8”值实际上是 Unicode 代码点,而不是这些代码点的 UTF-8 编码。我将此添加到您的代码中:

    StringBuilder buf = new StringBuilder();
    for (int i=0; i<str.length(); i++) buf.append(", ").append(Integer.toHexString(str.codePointAt(i)));
    System.out.println("     internal: "+buf.substring(2));

产生你展示的价值。

当这些代码点进行 UTF-8 编码时,它们会呈现为您实际看到的值。

使用在线Unicode 代码转换器来检查这一点。在“混合输入”框中输入字符串c720 d76c d6c8,然后单击“将数字转换为十六进制代码点”。

于 2013-07-25T19:06:00.660 回答
0

@JimGarrison 是对的:如果您尝试将原始字符串转换为 UTF-16 大端,您将看到“预期的 utf-8”-

    System.out.println("          try: " + bytesToHex(str.getBytes("UTF-16BE")));

这意味着,该字符串是:

"\uc720\ud76c\ud6c8"
于 2013-07-25T21:09:13.073 回答