Почему кодовые точки в диапазоне от U D800 до U DFFF были удалены из набора символов Unicode?

#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 Вот почему я сказал «кодировать кодовую точку как суррогатную пару «.