преобразовать ucs-4 в ucs-2
Юникод-значение символа ucs-4 '' равно 0001f923
, он автоматически изменяется на соответствующее значение \uD83E\uDD23
при копировании в java-код в intelliJ IDEA.
Java поддерживает только ucs-2, поэтому происходит преобразование ucs-4 в ucs-2.
Я хочу знать логику трансформации, но не нашел материала о ней.
2 ответа
https://en.wikipedia.org/wiki/UTF-16
От U+010000 до U+10FFFF
- 0x10000 вычитается из кодовой точки (U), оставляя 20-битное число (U') в диапазоне 0x00000–0xFFFFF. U определяется как не более 0x10FFFF.
- Старшие десять битов (в диапазоне 0x000–0x3FF) добавляются к 0xD800, чтобы получить первую 16-битную кодовую единицу или старший заменитель (W1), который будет находиться в диапазоне 0xD800–0xDBFF.
- Младшие десять битов (также в диапазоне 0x000–0x3FF) добавляются к 0xDC00, чтобы получить вторую 16-битную кодовую единицу или младший заменитель (W2), который будет находиться в диапазоне 0xDC00–0xDFFF.
Теперь с входной кодовой точкой \U1F923:
- \U1F923 - \U10000 = \UF923
- \UF923 = 1111100100100011 = 00001111100100100011 = [0000111110][0100100011] = [\U3E][\U123]
- \UD800 + \U3E = \UD83E
- \UDC00 + \U123 = \UDD23
- Результат: \UD83E\UDD23
Программирование:
public static void main(String[] args) {
int input = 0x1f923;
int x = input - 0x10000;
int highTenBits = x >> 10;
int lowTenBits = x & ((1 << 10) - 1);
int high = highTenBits + 0xd800;
int low = lowTenBits + 0xdc00;
System.out.println(String.format("[%x][%x]", high, low));
}
Хотя String
содержит Unicode как char
массив, где char
- это двухбайтовая кодировка UTF-16BE, также есть поддержка UCS4.
UCS4: UTF-32, "кодовые точки":
Кодовые точки Unicode, UCS4, представлены в Java как int
.
int[] ucs4 = new int[] {0x0001_f923};
String s = new String(ucs4, 0, ucs4.length);
ucs4 = s.codePoints().toArray();
Существуют кодировки, преобразования кодовых точек в UTF-16 и UTF-8, которые требуют более длинных последовательностей 2-байтовых или 1-байтовых значений соответственно. Кодировка выбрана таким образом, что 2/1-байтовые значения будут отличаться от любых других значений. Это означает, что такое значение не будет ошибочно соответствовать"/"
или любой другой строковый поиск. Это реализуется старшими битами, начиная с1...
а затем биты кодовой точки в формате big-endian (сначала наиболее значимые).
Вместо поиска UCS4 и UCS2 поиск по UTF-16 даст информацию об используемых алгоритмах.