в swift, как суррогатная пара utf16 представлена ​​​​в бите

В настоящее время я изучаю Swift, используя язык быстрого программирования книги 3.1.

В книге указано, что типы Swift String и Character полностью совместимы с юникодом, причем каждый символ представлен 21-битным скалярным значением юникода. Каждый символ можно просмотреть через utf8, 16, 32.

Я понимаю, как utf8 и utf32 работают на уровне байтов и битов, но мне трудно понять, как utf16 работает на уровне битов.

Я знаю, что для символов, кодовая точка которых может умещаться в 16 бит, utf16 просто представляет символ как 16-битное число. Но для символов, для представления которых требуется более 16 бит, используются два 16-битных блока (я полагаю, они называются суррогатной парой).

Но как два 16-битных блока представлены на битовом уровне?


person Thor    schedule 27.03.2017    source источник


Ответы (2)


"Скалярное значение Unicode"

Любая кодовая точка Unicode, кроме старшей и младшей суррогатной кодовых точек. Другими словами, диапазоны целых чисел от 0 до D7FF16 и от E00016 до 10FFFF16 включительно.

Каждое скалярное значение Unicode может быть представлено как последовательность из одной или двух единиц кода UTF-16, как описано в файле Стандарт Unicode:

Форма кодировки D91 UTF-16

Форма кодирования Unicode, которая присваивает каждому скалярному значению Unicode в диапазонах U+0000..U+D7FF и U+E000..U+FFFF одиночную 16-битную кодовую единицу без знака с тем же числовым значением, что и скалярное значение Unicode, и это присваивает каждому скалярному значению Unicode в диапазоне U+10000..U+10FFFF суррогатную пару в соответствии с таблицей 3-5.

Table 3-5. UTF-16 Bit Distribution

Scalar Value              UTF-16
xxxxxxxxxxxxxxxx          xxxxxxxxxxxxxxxx
000uuuuuxxxxxxxxxxxxxxxx  110110wwwwxxxxxx 110111xxxxxxxxxx

Note: wwww = uuuuu - 1

В «дополнительных плоскостях» (U+10000..U+10FFFF) есть 220 скалярных значений Unicode, что означает, что 20 бит достаточно, чтобы закодировать их все в суррогатной паре. Технически это делается путем вычитания 0x010000 из значения перед его разбиением на два блока по 10 бит.

person Martin R    schedule 27.03.2017

Диапазон utf16 D800...DFFF зарезервирован. Значения ниже и выше являются простыми 16-битными кодовыми точками. Значения D800..DBFF минус D800 — это старшие 10 битов 20-битных кодов за пределами FFFC. Следующие два байта содержат младшие 10 бит. Конечно, порядок следования байтов вмешивается в картину, заставляя всех нас желать, чтобы мы могли просто использовать utf8. Вздох.

person Mischa    schedule 27.03.2017
comment
спасибо за полезный комментарий. Итак, я предполагаю, что максимальное количество бит, которое может иметь символ utf16, составляет 20 бит? 10 бит из первого блока 16 бит и еще 10 бит из второго блока 16 бит? Но я думал, что скалярные значения Юникода представлены 21 битом. Значит ли это, что то, что может быть представлено скалярным значением Unicode (21 бит), не может быть представлено utf16 (20 бит)? - person Thor; 27.03.2017
comment
@TonyStark: см. en.wikipedia.org/wiki/UTF-16# U.2B10000_to_U.2B10FFFF: 0x010000 вычитается из кодовой точки, остается 20-битное число в диапазоне 0x000000..0x0FFFFF .... - person Martin R; 27.03.2017
comment
@MartinR, если utf16 представлен 20-битным числом, а скалярное значение юникода (которое является просто кодовой точкой для символов) представлено 21-битным числом, значит ли это, что какое-то скалярное значение юникода не может быть представлено utf16? - person Thor; 27.03.2017
comment
@TonyStark: Извините, я вас не понимаю. Все действительные кодовые точки Unicode от U+0 до U+10FFFF могут быть представлены как 1 или 2 кодовые единицы UTF-16, и в статье Википедии описывается, как это делается. - person Martin R; 27.03.2017
comment
@TonyStark: Возможно, эта цитата из статьи в Википедии развеет ваши сомнения: поскольку кодирование дополнительных плоскостей содержит 10 + 10 = 20 значащих битов, можно обрабатывать 2 ^ 20 кодовых точек, разделенных на 16 плоскостей по 2 ^ 16 кодовых точек в каждой. Включая отдельно управляемый базовый многоязычный уровень, всего существует 17 уровней. - person Martin R; 27.03.2017
comment
@MartinR большое спасибо за вашу помощь. Вы помогли мне несколько раз за последние несколько месяцев, я очень благодарен за всю вашу помощь. Так повезло, что такие люди, как вы, на stackoverflow помогают людям по всему миру. - person Thor; 27.03.2017