#unicode #encoding #character-encoding #utf-16
#unicode #кодирование #кодировка символов #utf-16
Вопрос:
Я изучаю кодировку UTF-16, и я прочитал, что если вы хотите представить кодовые точки в диапазоне от U 10000 до U 10FFFF, то вам придется использовать суррогатные пары, которые находятся в диапазоне от U D800 до U DFFF.
Итак, допустим, я хочу закодировать следующую кодовую точку: U 10123 (10000000100100011 в двоичном формате):
Сначала я расположил эту последовательность битов:
110110xxxxxxxxxxxx 110111xxxxxxxxxxxx
Затем я заполняю места с x двоичным форматом кодовой точки:
1101100001000000 1101110100100011 (D840 DD23 в шестнадцатеричном формате)
Я также читал, что кодовые точки в диапазоне от U D800 до U DFFF были удалены из набора символов Unicode, но я не понимаю, почему был удален этот диапазон!
Я имею в виду, что этот диапазон может быть легко закодирован в 4 байта, например, следующий кодированный формат UTF-16 кодовой точки U D812 (1101100000010010 в двоичном формате):
1101100000110110 1101110000010010 (D836 DC12 в шестнадцатеричном формате)
Примечание: В своих примерах я использовал UTF-16 с большим порядковым номером.
Комментарии:
1. Вы уверены, что U 10123 становится
D840 DD23
а неD800 DD23
нет?2. @Roland Illig Странно, когда я кодирую это вручную, я получаю
D840 DD23
, но когда я кодирую это с помощью этого онлайн-инструмента: r12a.github.io/apps/conversion , Я получаюD800 DD23
. Мой метод кодирования вручную неверен?3. Давайте назовем это зарезервированным вместо удаленного. Помогает в обнаружении ошибок, вы можете определить, кто ошибся, и отправить отчет об ошибке в нужное место. Другими примерами являются U FFFE (соответствует спецификации в обратном направлении) и U FFFF (слишком легко ошибиться, поскольку C-конец файла).
4. @Roland Illig Вы правы,
D800 DD23
это правильный ответ, что я сделал неправильно, так это то, что я забыл вычесть0x10000
из кодовой точки (это должно было быть первым шагом, который я делаю).
Ответ №1:
Кодовые точки U D800 — U DFFF зарезервированы исключительно1 для использования с UTF-16. Поскольку они не находятся в диапазоне от U 10000 до U 10FFFF, UTF-16 не будет кодировать их по отдельности с использованием суррогатных пар, поэтому было бы неоднозначно (и незаконно2), чтобы эти отдельные кодовые точки отображались не закодированными в последовательности UTF-16.
Согласно Unicode.org ЧАСТО ЗАДАВАЕМЫЕ вопросы по UTF-16:
1: Вопрос: Что такое суррогаты?
Ответ: Суррогаты — это кодовые точки из двух специальных диапазонов значений Unicode, зарезервированных для использования в качестве начального и конечного значений парных кодовых единиц в UTF-16. Начальные, также называемые старшими, заменители — от D800 16 до DBFF16, а конечные, или младшие, заменители — от DC00 16 до DFFF16. Они называются суррогатами, поскольку они представляют символы не напрямую, а только в виде пары.
2: Вопрос: Существуют ли какие-либо 16-разрядные значения, которые являются недопустимыми?
Ответ: Непарные суррогаты недопустимы в UTFs. К ним относятся любое значение в диапазоне от D800 16 до DBFF16, за которым не следует значение в диапазоне от DC0016 до DFFF16, или любое значение в диапазоне от DC00 16 до DFFF16, которому не предшествует значение в диапазоне от D800 16 до DBFF16.
Комментарии:
1. Ваша формулировка смешивает кодированные кодовые точки с кодовыми точками. Они не могут быть раскодированы в потоке UTF-16. Нет способа закодировать их в UTF-16. UTF-8 и UTF-32 могут их кодировать, но, как вы указали, они зарезервированы и не должны кодироваться.
Ответ №2:
У меня нет официального источника, подтверждающего это, но я полагаю, что это было сделано для предотвращения путаницы, чтобы вы не могли получить кодовую последовательность, которая могла быть интерпретирована как допустимый UTF-16, так и допустимый UCS-2. Потеря 2048 кодовых точек была ничем по сравнению с добавлением 1048576 новых.
Ответ №3:
Поскольку кодирование кодовой точки в качестве суррогатной пары начинается с вычитания 0x010000
, это привело бы к отрицательным числам. И смысл этого вычитания в том, чтобы разрешить еще 65536 кодовых точек вместо кодирования пропущенных 2048. Возможно, это окажется полезным, если в отдаленном будущем будет использовано все пространство кода.
Комментарии:
1. Вычитаются и кодируются в суррогатные пары только кодовые точки U 10000 — U 10FFFF. Кодовые точки U 0000 — U FFFF кодируются как есть, а не вычитаются.
2. @Remy Вот почему я сказал «кодировать кодовую точку как суррогатную пару «.