JAVA:从字符串中获取UTF-8十六进制值?

7

我希望能将一个原始的UTF-8字符串转换为十六进制字符串。 在下面的示例中,我已经创建了一个包含2个字母的UTF-8字符串样本。 然后我尝试获取十六进制值,但它给出了负数值。

我该如何使其给出05D005D1呢?

String a = "\u05D0\u05D1";
byte[] xxx = a.getBytes("UTF-8");

for (byte x : xxx) {
   System.out.println(Integer.toHexString(x));
}

谢谢。
2个回答

6

如果您想要得到代码点,请不要将其转换为像UTF-8这样的编码。使用Character.codePointAt

例如:

Character.codePointAt("\u05D0\u05D1", 0) // returns 1488, or 0x5d0

1
你想要UTF-8的十六进制值(0xD790)还是代码点(0x000005D0)?如果你想要代码点,使用 new String(bytes, "UTF-8") 将字节转换为字符串,然后使用 Character.codePointAt(...).toHexString() 来获取十六进制表示。 - ataylor
也许我漏掉了什么。 Character.codePointAt 没有 toHexString 方法,它返回一个整数。你能否给我一个完整的例子?谢谢。 - thedp
1
抱歉,toHexString是一个静态方法。System.out.println(Integer.toHexString(Character.codePointAt("\u05D0", 0)))将打印出5d0。如果您想在左侧用零填充它,请尝试使用System.out.printf("%08x", Character.codePointAt("\u05D0", 0)),它将打印000005d0 - ataylor

3

出现负值是因为 byte 的范围是从 -128 到 127。以下代码将产生正值:

String a = "\u05D0\u05D1";
byte[] xxx = a.getBytes("UTF-8");

for (byte x : xxx) {
    System.out.println(Integer.toHexString(x & 0xFF));
}

主要区别是它输出的是 x & 0xFF 而不仅仅是 x,这个操作将 byte 转换为 int,丢弃符号。

谢谢您的快速回复,但它仍然没有给出正确的值。 我正在尝试复制05D0的十六进制值,但代码给出的是d7 90。 - thedp
@thedp 这是因为你所编码的符号在UTF-8中被表示成这些字节。如果你想要接收你说的字节,你应该使用UTF-16。 - Malcolm
1
UTF-8编码不是你想象中的那样。每个值都被编码为多个字节。有关详细信息,请参见http://en.wikipedia.org/wiki/UTF-8#Description。 - sw1nn
1
没错。D7 90的二进制表示是11010111 10010000。这里第一个字节开头的110只是一个指示器,表示后面还有一个字节。第二个字节开头的10表示它不是第一个字节。如果我们去掉它们,我们得到以下数字10111 010000,恰好是16进制数5D0。这就是UTF-8解码过程的工作原理。 - Malcolm
感谢您向我解释这个主题。 - thedp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接