преобразовать 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 даст информацию об используемых алгоритмах.

Другие вопросы по тегам