Строка UTF-8 в порядковое значение: эквивалент Java для вывода Python

У меня такое ощущение, что это, скорее всего, дубликат, но я не могу его найти.

ПРИМЕЧАНИЕ. Мои знания 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, является предварительным условием для этого вопроса.


person Kevin Cruijssen    schedule 04.02.2019    source источник
comment
все строки в Java по умолчанию кодируются с помощью UTF-16: с точки зрения API (особенно .length) другого варианта нет.   -  person Tom Blodget    schedule 05.02.2019


Ответы (1)


Java byte подписан, вот откуда берутся отрицательные числа. Побитовые числа имеют одинаковое значение в обоих языках, просто способ их представления различен. Вы можете получить то же представление, что и в python, используя Byte.toUnsignedInt():

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]
person Jorn Vernee    schedule 04.02.2019
comment
Ах, вот в чем была разница. Спасибо! Я приму ваш ответ через несколько минут, когда смогу. - person Kevin Cruijssen; 04.02.2019