UTF-16

Поделись знанием:
Перейти к: навигация, поиск

UTF-16 (англ. Unicode Transformation Format) в информатике — один из способов кодирования символов из Юникода в виде последовательности 16-битных слов. Данная кодировка позволяет записывать символы Юникода в диапазонах U+0000..U+D7FF и U+E000..U+10FFFF (общим количеством 1 112 064). При этом каждый символ записывается одним или двумя словами (суррогатная пара).

Кодировка UTF-16 описана в приложении Q к международному стандарту ISO/IEC 10646, а также ей посвящён IETF RFC 2781 «UTF-16, an encoding of ISO 10646».





История появления

Первая версия Юникода (1991 г.) представляла собой 16-битную кодировку с фиксированной шириной символа; общее число разных символов было 216 (65 536). Во второй версии Юникода (1996 г.) было решено значительно расширить кодовую область; для сохранения совместимости с теми системами, где уже был реализован 16-битный Юникод, и была создана UTF-16. Область 0xD800—0xDFFF, отведённая для суррогатных пар, ранее принадлежала к области «символов для частного использования».

Поскольку в UTF-16 можно отобразить 220+216−2048 (1 112 064) символов, то это число и было выбрано в качестве новой величины кодового пространства Юникода.

Принцип кодирования

  DC00 DFFE DFFF
D800 010000 0103FE 0103FF
D801 010400 0107FE 0107FF
DBFF 10FC00 10FFFE  

В UTF-16 символы кодируются двухбайтовыми словами с использованием всех возможных диапазонов значений (от 0 до FFFF16). При этом можно кодировать символы Unicode в дипазонах 000016..D7FF16 и E00016..10FFFF16. Исключенный отсюда диапазон D80016..DFFF16 используется как раз для кодирования так называемых суррогатных пар — символов, которые кодируются двумя 16-битными словами.

Символы Unicode до FFFF16 включительно (исключая диапазон для суррогатов) записываются как есть 16-битным словом.

Символы же в диапазоне 1000016..10FFFF16 (больше 16 бит) кодируются по следующей схеме:

  • Код символа арифметически сдвигается до нуля (из него вычитается минимальное число 1000016). В результате получится значение от нуля до FFFFF16, которое занимает до 20 бит.
  • Старшие 10 бит (число в диапазоне 000016..03FF16) суммируются с D80016, и результат идёт в лидирующее (первое) слово, которое входит в диапазон D80016..DBFF16.
  • Младшие 10 бит (тоже число в диапазоне 000016..03FF16) суммируются с DC0016, и результат идёт в последующее (второе) слово, которое входит в диапазон DC0016..DFFF16.

В обоих словах старшие 6 бит используются для обозначения суррогата. Биты с 11 по 15 (если вести отсчёт от нуля) имеют значения 110112, а 10-й бит содержит 0 у лидирующего слова и 1 — у последующего. В связи с этим можно легко определить, к чему относится каждое слово.

Порядок байт

Один символ кодировки UTF-16 представлен последовательностью двух байтов или двух пар байтов. Который из двух идёт впереди, старший или младший, зависит от порядка байтов. Систему, совместимую с процессорами x86, называют little endian, а с процессорами m68k и SPARC — big endian.

Для определения порядка байтов используется метка порядка байтов (англ. Byte order mark). В начале текста записывается код U+FEFF. При считывании, если вместо U+FEFF считалось U+FFFE, значит порядок байтов обратный, поскольку символа с кодом и U+FFFE в Юникоде нет. Так как в кодировке UTF-8 не используются значения 0xFE и 0xFF, можно использовать метку порядка байтов как признак, позволяющий различать UTF-16 и UTF-8.

UTF-16LE и UTF-16BE

Предусмотрена также возможность внешнего указания порядка байтов — для этого кодировка должна быть описана как UTF-16LE или UTF-16BE (little-endian / big-endian), а не просто UTF-16. В этом случае метка порядка байтов (U+FEFF) не нужна.

UTF-16 в ОС Windows

В API Win32, распространённом в современных версиях операционной системы Microsoft Windows, имеется два способа представления текста: в форме традиционных 8-битных кодовых страниц и в виде UTF-16.

При использовании UTF-16, Windows не накладывает ограничений на прикладные программы касательно кодирования текстовых файлов, позволяя им использовать как UTF-16LE, так и UTF-16BE посредством установки и трактовки соответствующей метки порядка байтов. Однако внутренний формат Windows - всегда UTF-16LE. Этот момент следует учитывать при работе с исполняемыми файлами, использующими юникодовые версии функций WinAPI. Строки в них всегда кодируются в UTF-16LE[1].

В файловых системах NTFS, а также FAT с поддержкой длинных имён, имена файлов записываются также в UTF-16LE.

Примеры процедур

Примеры ниже записаны на псевдокоде и в них не учитывается маска порядка байт — они лишь показывают суть кодирования. Порядок байт — от младшего к старшему (Little-Endian, интеловский x86). Тип Word — двухбайтовое слово (16-битное беззнаковое целое), а тип UInt32 — 32-битное беззнаковое целое. Шестнадцатиричные значения начинаются со знака доллара «$».

Кодирование

В примере WriteWord() — условная процедура, которая пишет одно слово (при этом сдвигает внутренний указатель). Функция LoWord() возвращает младшее слово от 32-битного целого (старшие биты не глядя отбрасываются).

// Допустимые значения Code: $0000..$D7FF, $E000..$10FFFF.
Procedure WriteUTF16Char(Code: UInt32)
    If (Code < $10000) Then
        WriteWord(LoWord(Code))
    Else
        Code = Code - $10000
        Var Lo10: Word = LoWord(Code And $3FF)
        Var Hi10: Word = LoWord(Code Shr 10)
        WriteWord($D800 Or Hi10)
        WriteWord($DC00 Or Lo10)
    End If
End Procedure

Раскодирование

В примере ReadWord() читает слово из потока (сдвигая при этом внутренний указатель). Она же при необходимости может корректировать порядок байт. Функция WordToUInt32 расширяет двухбайтовое слово до четырёхбайтового беззнакового целого, заполняя старшие биты нулями. Error() прерывает выполнение (по сути исключение).

// В случае успеха возвращаются значения
// в диапазонах $0000..$D7FF и $E000..$10FFFF.
Function ReadUTF16Char: UInt32
    Var Leading:  Word  // Лидирующее (первое) слово.
    Var Trailing: Word  // Последующее (второе) слово.

    Leading = ReadWord();
    If (Leading < $D800) Or (Leading > $DFFF) Then
        Return WordToUInt32(Leading)
    Else If (Leading >= $DC00) Then
        Error("Недопустимая кодовая последовательность.")
    Else
        Var Code: UInt32
        Code = WordToUInt32(Leading And $3FF) Shl 10
        Trailing = ReadWord()
        If ((Trailing < $DC00) Or (Trailing > $DFFF)) Then
            Error("Недопустимая кодовая последовательность.")
        Else
            Code = Code Or WordToUInt32(Trailing And $3FF)
            Return (Code + $10000)
        End If
    End If
End Function

Напишите отзыв о статье "UTF-16"

Примечания

  1. [msdn.microsoft.com/en-us/library/windows/desktop/dd374101(v=vs.85).aspx Using Byte Order Marks]

Ссылки

  • [www.unicode.org/notes/tn12/ Unicode Technical Note #12: Обработка UTF-16]  (англ.)
  • [www.unicode.org/faq/utf_bom.html#utf16-11 Unicode FAQ: В чём разница между UCS-2 и UTF-16?]  (англ.)
  • [tools.ietf.org/html/rfc2781 RFC 2781: UTF-16, an encoding of ISO 10646]  (англ.)
  • [www.unicode.org/ Полное описание стандарта Unicode]  (англ.)
  • [www.cl.cam.ac.uk/~mgk25/ucs/ISO-10646-UTF-16.html ISO-10646-UTF-16 (Информация о конвертировании больших значений в два слова UTF-16)]
Кодировки символов
Основы алфавиттекст (файлданные) • набор символовконверсия
Исторические кодировки Докомп.: семафорная (Макарова)МорзеБодоМТК-2
Комп.: 6-битнаяУППRADIX-50EBCDIC (ДКОИ-8) • КОИ-7ISO 646
современное
8-битное
представление
символы ASCII (управляющиепечатные) • не-ASCII (псевдографика)
8-битные код.стр. Кириллица: КОИ-8Основная кодировкаMacCyrillic
ISO 8859 1 (лат.)2345 (кир.)6789101112131415 (€)16
Windows 12501251 (кир.)1252125312541255125612571258WGL4
IBM & DOS 437850852855866 «альт.»МИКНИИ ЭВМ
Многобайтные Традиционные DBCS (GB2312) • HTML
Unicode UTF-32UTF-16UTF-8список символов (кириллица)
Связанные темы интерфейс пользователяраскладка клавиатурылокальперевод строкишрифттранслитнестандартные шрифты
Утилиты iconvrecode

Отрывок, характеризующий UTF-16

После отъезда Метивье старый князь позвал к себе дочь и вся сила его гнева обрушилась на нее. Она была виновата в том, что к нему пустили шпиона. .Ведь он сказал, ей сказал, чтобы она составила список, и тех, кого не было в списке, чтобы не пускали. Зачем же пустили этого мерзавца! Она была причиной всего. С ней он не мог иметь ни минуты покоя, не мог умереть спокойно, говорил он.
– Нет, матушка, разойтись, разойтись, это вы знайте, знайте! Я теперь больше не могу, – сказал он и вышел из комнаты. И как будто боясь, чтобы она не сумела как нибудь утешиться, он вернулся к ней и, стараясь принять спокойный вид, прибавил: – И не думайте, чтобы я это сказал вам в минуту сердца, а я спокоен, и я обдумал это; и это будет – разойтись, поищите себе места!… – Но он не выдержал и с тем озлоблением, которое может быть только у человека, который любит, он, видимо сам страдая, затряс кулаками и прокричал ей:
– И хоть бы какой нибудь дурак взял ее замуж! – Он хлопнул дверью, позвал к себе m lle Bourienne и затих в кабинете.
В два часа съехались избранные шесть персон к обеду. Гости – известный граф Ростопчин, князь Лопухин с своим племянником, генерал Чатров, старый, боевой товарищ князя, и из молодых Пьер и Борис Друбецкой – ждали его в гостиной.
На днях приехавший в Москву в отпуск Борис пожелал быть представленным князю Николаю Андреевичу и сумел до такой степени снискать его расположение, что князь для него сделал исключение из всех холостых молодых людей, которых он не принимал к себе.
Дом князя был не то, что называется «свет», но это был такой маленький кружок, о котором хотя и не слышно было в городе, но в котором лестнее всего было быть принятым. Это понял Борис неделю тому назад, когда при нем Ростопчин сказал главнокомандующему, звавшему графа обедать в Николин день, что он не может быть:
– В этот день уж я всегда езжу прикладываться к мощам князя Николая Андреича.
– Ах да, да, – отвечал главнокомандующий. – Что он?..
Небольшое общество, собравшееся в старомодной, высокой, с старой мебелью, гостиной перед обедом, было похоже на собравшийся, торжественный совет судилища. Все молчали и ежели говорили, то говорили тихо. Князь Николай Андреич вышел серьезен и молчалив. Княжна Марья еще более казалась тихою и робкою, чем обыкновенно. Гости неохотно обращались к ней, потому что видели, что ей было не до их разговоров. Граф Ростопчин один держал нить разговора, рассказывая о последних то городских, то политических новостях.
Лопухин и старый генерал изредка принимали участие в разговоре. Князь Николай Андреич слушал, как верховный судья слушает доклад, который делают ему, только изредка молчанием или коротким словцом заявляя, что он принимает к сведению то, что ему докладывают. Тон разговора был такой, что понятно было, никто не одобрял того, что делалось в политическом мире. Рассказывали о событиях, очевидно подтверждающих то, что всё шло хуже и хуже; но во всяком рассказе и суждении было поразительно то, как рассказчик останавливался или бывал останавливаем всякий раз на той границе, где суждение могло относиться к лицу государя императора.
За обедом разговор зашел о последней политической новости, о захвате Наполеоном владений герцога Ольденбургского и о русской враждебной Наполеону ноте, посланной ко всем европейским дворам.
– Бонапарт поступает с Европой как пират на завоеванном корабле, – сказал граф Ростопчин, повторяя уже несколько раз говоренную им фразу. – Удивляешься только долготерпению или ослеплению государей. Теперь дело доходит до папы, и Бонапарт уже не стесняясь хочет низвергнуть главу католической религии, и все молчат! Один наш государь протестовал против захвата владений герцога Ольденбургского. И то… – Граф Ростопчин замолчал, чувствуя, что он стоял на том рубеже, где уже нельзя осуждать.
– Предложили другие владения заместо Ольденбургского герцогства, – сказал князь Николай Андреич. – Точно я мужиков из Лысых Гор переселял в Богучарово и в рязанские, так и он герцогов.
– Le duc d'Oldenbourg supporte son malheur avec une force de caractere et une resignation admirable, [Герцог Ольденбургский переносит свое несчастие с замечательной силой воли и покорностью судьбе,] – сказал Борис, почтительно вступая в разговор. Он сказал это потому, что проездом из Петербурга имел честь представляться герцогу. Князь Николай Андреич посмотрел на молодого человека так, как будто он хотел бы ему сказать кое что на это, но раздумал, считая его слишком для того молодым.
– Я читал наш протест об Ольденбургском деле и удивлялся плохой редакции этой ноты, – сказал граф Ростопчин, небрежным тоном человека, судящего о деле ему хорошо знакомом.
Пьер с наивным удивлением посмотрел на Ростопчина, не понимая, почему его беспокоила плохая редакция ноты.
– Разве не всё равно, как написана нота, граф? – сказал он, – ежели содержание ее сильно.
– Mon cher, avec nos 500 mille hommes de troupes, il serait facile d'avoir un beau style, [Мой милый, с нашими 500 ми тысячами войска легко, кажется, выражаться хорошим слогом,] – сказал граф Ростопчин. Пьер понял, почему графа Ростопчина беспокоила pедакция ноты.
– Кажется, писак довольно развелось, – сказал старый князь: – там в Петербурге всё пишут, не только ноты, – новые законы всё пишут. Мой Андрюша там для России целый волюм законов написал. Нынче всё пишут! – И он неестественно засмеялся.
Разговор замолк на минуту; старый генерал прокашливаньем обратил на себя внимание.
– Изволили слышать о последнем событии на смотру в Петербурге? как себя новый французский посланник показал!
– Что? Да, я слышал что то; он что то неловко сказал при Его Величестве.
– Его Величество обратил его внимание на гренадерскую дивизию и церемониальный марш, – продолжал генерал, – и будто посланник никакого внимания не обратил и будто позволил себе сказать, что мы у себя во Франции на такие пустяки не обращаем внимания. Государь ничего не изволил сказать. На следующем смотру, говорят, государь ни разу не изволил обратиться к нему.
Все замолчали: на этот факт, относившийся лично до государя, нельзя было заявлять никакого суждения.
– Дерзки! – сказал князь. – Знаете Метивье? Я нынче выгнал его от себя. Он здесь был, пустили ко мне, как я ни просил никого не пускать, – сказал князь, сердито взглянув на дочь. И он рассказал весь свой разговор с французским доктором и причины, почему он убедился, что Метивье шпион. Хотя причины эти были очень недостаточны и не ясны, никто не возражал.
За жарким подали шампанское. Гости встали с своих мест, поздравляя старого князя. Княжна Марья тоже подошла к нему.