Преобразование индекса UTF-16 в индекс, совместимый с UTF-8

#utf-8 #utf-16

#utf-8 #utf-16

Вопрос:

В настоящее время я работаю с API Telegram, и в одном из его методов он возвращает следующую информацию:

  • фрагмент текста
  • смещение в кодовых единицах UTF-16
  • длина в кодовых единицах UTF-16

На моем языке программирования Rust все строки являются допустимыми в формате UTF-8. Это означает, что смещения UTF-16 не являются полезными сразу, поскольку они могут быть отключены на переменную величину (из-за 1 или 3 байтовых кодовых точек). Однобайтовая кодовая точка в UTF-8 соответствует двухбайтовой в UTF-16, поэтому я не могу просто индексировать строку UTF-8, поскольку я могу находиться за пределами границ кодовой точки.

Теперь мне интересно: есть ли способ преобразовать его в действительный UTF-8 без перебора строки UTF-8 или если информация бесполезна один раз в UTF-8?

Комментарии:

1. Я не помечал Rust, поскольку это лишь случайно связано с вопросом

2. Это забавный интерфейс. Текст передается в формате UTF-8, но смещения указаны в формате UTF-16. Вероятно, это имеет смысл для программистов Java и .NET, которые преобразуют текст в строку, которая внутренне использует UTF-16. В Rust вам придется перебирать строку (или преобразовывать ее в массив UTF-16). Из-за переменной длины UTF-8 только смещения UTF-8 работают для прямого доступа к части строки UTF-8 без итерации.

3. Как кодируется кодовая точка> 0xFFFF? Какой такой интерфейс (и вы говорите от 1 до 3 [не 4] байт), я бы заподозрил, что каждая единица кода преобразуется в UTF-8. Не могли бы вы это проверить? Примечание: строго говоря, такой UTF-8 не является допустимой строкой в Юникоде: вы получаете неверную кодовую точку, но, возможно, можно использовать суррогаты в качестве кодовых точек [численно разрешено UTF-8, но результаты не являются строкой в Юникоде]

4. В любом случае необходимо выполнить итерацию, но вы должны сделать это в любом случае, по соображениям безопасности: вы не хотите получать вырожденный UTF-8 (и вообще вырожденную последовательность кодовых точек Unicode). Фильтры могут не работать в таких случаях (например, реализации UTF-8 имеют различные псевдонимы NUL )

5. Как UTF-8, так и UTF-16 являются кодировками Unicode переменной длины . Хотя обе эти упрощенные формы преобразования кода предоставляют средства для передачи текста в форме «кодовых точек», даже они не обязательно означают то, что пользователь может распознать как «символ». Правильным термином, вероятно, является «графема», которая представляет собой объем текста, то есть единую репрезентативную «единицу», однако они могут, например, графемы, включая сочетание диакритических знаков, или флаги , использовать более одной кодовой точки для передачи графемы, которая их представляет.