UTF-8 字符串到序数值:Java 相当于 Python 输出

UTF-8 string to ordinal value: Java equivalent for Python output

我感觉这很可能是重复的,但我找不到它。

注意:我的 Python 知识非常有限,所以我不能 100% 确定 Python 中的字符串、字节和编码是如何完成的。我对一般编码的了解也不是太多..

假设我们有字符串 "Aä$$€h"。它包含三个不同的普通 ASCII 字符 (A$h) 和两个非 ASCII 字符 (ä€)。在 Python 中,我们有以下代码:

# coding: utf-8
input = u'Aä$$€h'
print [ord(c) for c in input.encode('utf-8')]
# Grouped per character:
print [[ord(x) for x in c.encode('utf-8')] for c in input_code]

这将输出:

[65, 195, 164, 36, 36, 226, 130, 172, 104]
[[65], [195, 164], [36], [36], [226, 130, 172], [104]]

Try it online.

现在我正在寻找一个 Java 等价物来提供相同的整数数组。我知道 Java 中的所有字符串在默认情况下都是用 UTF-16 编码的,只有字节数组可以有实际的编码。我认为以下代码会给出我预期的结果:

String input = "Aä$$€h";
byte[] byteArray = input.getBytes(java.nio.charset.StandardCharsets.UTF_8);
System.out.println(java.util.Arrays.toString(byteArray));

但不幸的是,它给出了以下结果:

[65, -61, -92, 36, 36, -30, -126, -84, 104]

Try it online.

我不确定这些负值是从哪里来的..

所以我的问题主要是这样的:

给定 Java 中包含非 ASCII 字符(即 "Aä$$€h")的字符串,输出其序号 UTF-8 整数,类似于 Python ord 函数在 UTF-8 编码字节上执行。这个问题的第一部分,我们已经有一个 Java 字符串,是这个问题的前提条件。

Java byte 是有符号的,这就是负数的来源。按位计算,数字在两种语言中具有相同的值,只是表示方式不同。您可以使用 Byte.toUnsignedInt():

获得与 python 中相同的表示
String input = "Aä$$€h";
byte[] byteArray = input.getBytes(java.nio.charset.StandardCharsets.UTF_8);
int[] ints = new int[byteArray.length];
for(int i = 0; i < ints.length; i++) {
    ints[i] = Byte.toUnsignedInt(byteArray[i]);
}
System.out.println(java.util.Arrays.toString(ints));

打印:

[65, 195, 164, 36, 36, 226, 130, 172, 104]