Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

UTF-16 (16 бит Unicode , преобразование формата) представляет собой символ , кодирующий способен кодировать все 1,112,064 не- суррогатной кодовые точки из Unicode (на самом деле это число кодовых точек диктуется конструкцией UTF-16). Кодирование имеет переменную длину , поскольку кодовые точки кодируются с помощью одной или двух 16-битных кодовых единиц . UTF-16 возник на основе более ранней 16-разрядной кодировки фиксированной ширины, известной как UCS-2 (для 2-байтового универсального набора символов), когда стало ясно, что требуется более 2 16 (65 536) кодовых точек. [1]

UTF-16 используется внутри таких систем, как Microsoft Windows , язык программирования Java и JavaScript / ECMAScript. Он также часто используется для обычного текста и файлов данных обработки текста в MS Windows. Он редко используется для файлов в Unix-подобных системах. По состоянию на май 2019 года Microsoft, похоже, изменила курс и теперь поддерживает и рекомендует использовать UTF-8 . [2]

UTF-16 - единственная веб-кодировка, несовместимая с ASCII , [3] и никогда не завоевывающая популярности в Интернете, где она используется менее чем на 0,01% (1 сотая 1%) веб-страниц. [4] UTF-8 для сравнения используется примерно 95% всех веб-страниц. [5] Web Hypertext Application Technology Рабочая группа (WHATWG) считает UTF-8 «обязательное кодирование для всех [текст]» и что по соображениям безопасности приложений браузер не должны использовать UTF-16. [6]

История [ править ]

В конце 1980-х годов началась работа по разработке единой кодировки для «универсального набора символов» ( UCS ), который заменит более ранние языковые кодировки единой скоординированной системой. Цель заключалась в том, чтобы включить все необходимые символы из большинства языков мира, а также символы из технических областей, таких как наука, математика и музыка. Первоначальная идея заключалась в замене типичных 256-символьных кодировок, которые требовали 1 байт на символ, кодировкой с использованием 65 536 (2 16 ) значений, что потребовало бы 2 байта (16 бит) на символ.

Две группы работали над этим параллельно: ISO / IEC JTC 1 / SC 2 и Unicode Consortium , последний представлял в основном производителей компьютерного оборудования. Обе группы попытались синхронизировать свои назначения символов, чтобы развивающиеся кодировки были взаимно совместимы. Раннее двухбайтовое кодирование первоначально называлось «Unicode», но теперь называется «UCS-2». [7]

Когда становилось все более ясно, что 2 16 символов недостаточно, [1] IEEE ввел большее 31-битное пространство и кодировку ( UCS-4 ), которая требовала 4 байта на символ. Консорциум Unicode сопротивлялся этому как потому, что 4 байта на символ занимали много памяти и дискового пространства, так и потому, что некоторые производители уже вложили значительные средства в технологию 2 байта на символ. Схема кодирования UTF-16 была разработана как компромисс и представлена ​​в версии 2.0 стандарта Unicode в июле 1996 года. [8] Она полностью указана в RFC 2781 , опубликованном в 2000 году IETF . [9] [10]

В кодировке UTF-16 кодовые точки меньше 2 16 кодируются с помощью одной 16-битной кодовой единицы, равной числовому значению кодовой точки, как в более старой UCS-2. Новые кодовые точки больше или равные 2 16 кодируются составным значением с использованием двух 16-битных кодовых единиц. Эти две 16-битные кодовые единицы выбираются из диапазона 0xD800–0xDFFF (который ранее не был назначен символам). Значения в этом диапазоне не используются в качестве символов, и UTF-16 не предоставляет законного способа кодировать их как отдельные кодовые точки. Таким образом, поток UTF-16 состоит из одиночных 16-битных кодовых точек за пределами этого диапазона (для кодовых точек в BMP) и пар 16-битных значений внутри этого диапазона (для кодовых точек выше BMP).

UTF-16 указан в последних версиях как международного стандарта ISO / IEC 10646, так и стандарта Unicode. «UCS-2 теперь следует считать устаревшим. Он больше не относится к форме кодирования в 10646 или стандарте Unicode». [11] С 2020 года не планируется ни расширение UTF-16 для поддержки большего количества кодовых точек, ни замена кода суррогатами, поскольку это нарушит Политику стабильности Unicode в отношении общей категории или суррогатных кодовых точек. [12] Пример идеи, которую можно было бы принять, - выделить другое значение BMP для префикса тройки суррогатов low, low, high (с измененным внутренним порядком, чтобы он не мог сопоставить суррогатную пару при поиске), что позволяет 2 30 больше кодовых точек, которые должны быть закодированы, однако изменение цели кодовой точки запрещено (использование префикса также запрещено, поскольку два из этих символов рядом друг с другом будут соответствовать суррогатной паре) или выделение двух плоскостей для суррогатов для 2 ² больше кодовых точек в восьми байтах в UTF-8 и UTF-16.

Описание [ править ]

Каждый символ Unicode кодируется в виде одной или двух 16-битных кодовых единиц . То, как эти 16-битные коды хранятся как байты, зависит от порядка байтов текстового файла или протокола связи.

От U + 0000 до U + D7FF и от U + E000 до U + FFFF [ редактировать ]

И UTF-16, и UCS-2 кодируют кодовые точки в этом диапазоне как одиночные 16-битные кодовые единицы, которые численно равны соответствующим кодовым точкам. Эти кодовые точки в базовой многоязычной плоскости (BMP) являются единственными кодовыми точками, которые могут быть представлены в UCS-2. [ необходима цитата ] Начиная с Unicode 9.0, некоторые современные нелатинские азиатские, ближневосточные и африканские алфавиты выходят за пределы этого диапазона, как и большинство символов эмодзи .

Кодовые точки от U + 010000 до U + 10FFFF [ править ]

Кодовые точки из других плоскостей (называемые дополнительными плоскостями ) кодируются как две 16-битные кодовые единицы, называемые суррогатной парой , по следующей схеме:

  • 0x10000 вычитается из кодовой точки (U) , оставляя 20-битное число (U ') в диапазоне шестнадцатеричных чисел 0x00000–0xFFFFF. Обратите внимание, что для этих целей значение U не должно превышать 0x10FFFF.
  • Старшие десять битов (в диапазоне 0x000–0x3FF) добавляются к 0xD800, чтобы получить первую 16-битную кодовую единицу или старший заменитель (W1) , который будет находиться в диапазоне 0xD800–0xDBFF .
  • Младшие десять битов (также в диапазоне 0x000–0x3FF) добавляются к 0xDC00, чтобы получить вторую 16-битную кодовую единицу или младший суррогат (W2) , который будет находиться в диапазоне 0xDC00–0xDFFF .

Визуально проиллюстрированное распределение U ' между W1 и W2 выглядит следующим образом: [13]

U '= yyyyyyyyyyxxxxxxxxxx // U - 0x10000W1 = 110110yyyyyyyyyy // 0xD800 + yyyyyyyyyyW2 = 110111xxxxxxxxxx // 0xDC00 + xxxxxxxxxx

Высокие суррогатный и низкие суррогатный также известны как «ведущий» и «задняя» суррогаты, соответственно, аналогичные передние и задние байты UTF-8. [14]

Поскольку диапазоны для высоких суррогатов ( 0xD800–0xDBFF ), низких суррогатов ( 0xDC00–0xDFFF ) и допустимых символов BMP (0x0000–0xD7FF, 0xE000–0xFFFF) не пересекаются , суррогат не может соответствовать символу BMP, или чтобы две соседние кодовые единицы выглядели как законная суррогатная пара . Это значительно упрощает поиск. Это также означает , что UTF-16 является самосинхронизируется на 16-битные словах: начинает ли блок коды символ может быть определен без рассмотрения ранее единиц коды (т.е. типа блока кодаможно определить по диапазонам значений, в которые он попадает). UTF-8 разделяет эти преимущества, но многие более ранние схемы многобайтового кодирования (такие как Shift JIS и другие азиатские многобайтовые кодировки) не допускали однозначного поиска и могли быть синхронизированы только путем повторного синтаксического анализа с начала строки (UTF -16 не является самосинхронизирующимся, если один байт потерян или если обход начинается со случайного байта).

Поскольку все наиболее часто используемые символы находятся в BMP, обработка суррогатных пар часто не проверяется тщательно. Это приводит к постоянным ошибкам и потенциальным дырам в безопасности даже в популярном и хорошо изученном прикладном программном обеспечении (например, CVE - 2008-2938 , CVE- 2012-2135 ).

В Дополнительных Плоскостях содержат эмодзи , исторические сценарии, менее часто используемые символы, меньше используемую китайскую идеограмму и т.д. Поскольку кодирование дополнительных плоскостей содержит 20 старших бит (10 из 16 бит в каждом из высоких и низких суррогатов ), 2 20 кодовых точек могут быть закодированы, разделены на 16 плоскостей по 2 16 кодовых точек в каждой. Включая отдельно управляемый базовый многоязычный самолет, всего 17 самолетов.

U + D800 в U + DFFF [ править ]

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

Однако UCS-2, UTF-8 и UTF-32 могут кодировать эти кодовые точки тривиальными и очевидными способами, и большое количество программного обеспечения делает это, даже если в стандарте указано, что такие схемы следует рассматривать как ошибки кодирования.

Можно однозначно закодировать непарный суррогат (высокий суррогатный код, за которым не следует низкий, или низкий, за которым не следует высокий) в формате UTF-16, используя кодовую единицу, равную кодовой точке. . Результат не является допустимым UTF-16, но большинство реализаций кодировщика и декодера UTF-16 делают это тогда при преобразовании между кодировками. [ необходима цитата ] Windows допускает использование непарных суррогатов в именах файлов и других местах, что обычно означает, что они должны поддерживаться программным обеспечением, несмотря на то, что они исключены из стандарта Unicode.

Примеры [ править ]

Чтобы кодировать U + 10437 (𐐷) в UTF-16:

  • Вычтите 0x10000 из кодовой точки, оставив 0x0437.
  • Для старшего суррогата сдвиньте вправо на 10 (разделите на 0x400), затем добавьте 0xD800, в результате получится 0x0001 + 0xD800 = 0xD801.
  • Для младшего суррогата возьмите младшие 10 бит (остаток от деления на 0x400), затем добавьте 0xDC00, в результате получится 0x0037 + 0xDC00 = 0xDC37.

Чтобы декодировать U + 10437 (𐐷) из UTF-16:

  • Возьмите старший суррогат (0xD801) и вычтите 0xD800, затем умножьте на 0x400, в результате получится 0x0001 × 0x400 = 0x0400.
  • Возьмите младший суррогат (0xDC37) и вычтите 0xDC00, в результате получится 0x37.
  • Сложите эти два результата вместе (0x0437) и, наконец, добавьте 0x10000, чтобы получить окончательную декодированную кодовую точку UTF-32, 0x10437.

В следующей таблице приведены данные об этом, а также о других преобразованиях. Цвета показывают, как биты из кодовой точки распределяются между байтами UTF-16. Дополнительные биты, добавленные в процессе кодирования UTF-16, показаны черным.

Схемы кодирования порядка байтов [ править ]

UTF-16 и UCS-2 создают последовательность из 16-битных кодовых единиц. Поскольку большинство протоколов связи и хранения определены для байтов, и каждый блок, таким образом, занимает два 8-битных байта, порядок байтов может зависеть от порядка байтов (порядок байтов) архитектуры компьютера.

Чтобы помочь в распознавании порядка байтов кодовых единиц, UTF-16 позволяет метке порядка байтов (BOM), кодовой точке со значением U + FEFF, предшествовать первому фактическому кодированному значению. [nb 1] (U + FEFF - невидимый неразрывный пробел нулевой ширины / символ ZWNBSP.) [nb 2] Если байтовая архитектура декодера совпадает с архитектурой кодера, декодер обнаруживает значение 0xFEFF, но противоположное -конечный декодер интерпретирует BOM как несимвольное значение U + FFFE, зарезервированное для этой цели. Этот неверный результат дает подсказку для выполнения замены байтов для оставшихся значений.

Если спецификация отсутствует, RFC 2781 рекомендует [nb 3] использовать кодировку с прямым порядком байтов. На практике, из-за того, что Windows по умолчанию использует прямой порядок следования байтов, многие приложения предполагают обратную кодировку. Также надежно обнаруживать порядок байтов путем поиска нулевых байтов при условии, что символы меньше U + 0100 очень распространены. Если большее количество четных байтов (начиная с 0) равны нулю, то это обратный порядок байтов.

Стандарт также позволяет явно указывать порядок байтов, указывая UTF-16BE или UTF-16LE в качестве типа кодировки. Когда порядок байтов указан явно таким образом, спецификация специально не должна добавляться к тексту, а U + FEFF в начале следует обрабатывать как символ ZWNBSP. Большинство приложений игнорируют спецификации во всех случаях, несмотря на это правило.

Для интернет- протоколов IANA утвердила «UTF-16», «UTF-16BE» и «UTF-16LE» в качестве имен для этих кодировок (имена регистронезависимы). Псевдонимы UTF_16 или UTF16 могут иметь значение в некоторых языках программирования или программных приложениях, но они не являются стандартными именами в Интернет-протоколах.

Подобные обозначения, UCS-2BE и UCS-2LE , используются для отображения версий UCS-2 .

Использование [ править ]

UTF-16 используется для текста в API ОС всех поддерживаемых в настоящее время версий Microsoft Windows (включая по крайней мере все, начиная с Windows CE / 2000 / XP / 2003 / Vista / 7 [15] ), включая Windows 10 . Начиная с инсайдерской сборки 17035 и апрельского обновления 2018 года в нее добавлена ​​поддержка UTF-8, и с мая 2019 года Microsoft рекомендует программному обеспечению использовать ее вместо UTF-16. [2] Старые системы Windows NT (до Windows 2000) поддерживают только UCS-2. [16]В Windows XP код выше U + FFFF не входит ни в один шрифт, поставляемый с Windows для европейских языков. [17] [18] Файлы и сетевые данные, как правило, представляют собой смесь кодировок UTF-16, UTF-8 и устаревших байтовых кодировок.

Я IBM операционная система определяет CCSID ( код страницы ) 13488 для UCS-2 кодирования и CCSID 1200 для UTF-16 кодировке, хотя система обрабатывает их обоих , как UTF-16. [19]

UTF-16 используется операционными системами Qualcomm BREW ; в .NET среды; и инструментарий кроссплатформенных графических виджетов Qt .

ОС Symbian, используемая в телефонах Nokia S60 и Sony Ericsson UIQ, использует UCS-2. Мобильные телефоны iPhone используют UTF-16 для службы коротких сообщений вместо UCS-2, описанного в стандартах 3GPP TS 23.038 ( GSM ) и IS-637 ( CDMA ). [20]

Joliet файловой системы , используется в CD-ROM СМИ, кодирует имена файлов с использованием UCS-2be (до шестидесяти четырех символов Unicode в имени файла).

Python языковая среда официально использует только UCS-2 внутри , начиная с версии 2.0, но декодер UTF-8 «Unicode» производит правильно UTF-16. Начиная с Python 2.2, поддерживаются «широкие» сборки Unicode, которые вместо этого используют UTF-32; [21] они в основном используются в Linux. Python 3.3 больше никогда не использует UTF-16, вместо этого кодировка, которая дает наиболее компактное представление для данной строки, выбирается из ASCII / Latin-1, UCS-2 и UTF-32. [22]

Первоначально в Java использовался UCS-2, а в J2SE 5.0 добавлена ​​поддержка дополнительных символов UTF-16 .

JavaScript может использовать UCS-2 или UTF-16. [23] Начиная с ES2015, в язык были добавлены строковые методы и флаги регулярных выражений, которые позволяют обрабатывать строки с точки зрения независимого от кодирования.

Во многих языках строки в кавычках нуждаются в новом синтаксисе для цитирования не-BMP символов, поскольку "\uXXXX"синтаксис в стиле C явно ограничивает себя 4 шестнадцатеричными цифрами. Следующие ниже примеры иллюстрируют синтаксис символа не-BMP «𝄞» (U + 1D11E, МУЗЫКАЛЬНЫЙ СИМВОЛ G CLEF). Наиболее распространенным (используемым C ++ , C # , D и некоторыми другими языками) является использование верхнего регистра 'U' с 8 шестнадцатеричными цифрами, например "\U0001D11E". [24] В регулярных выражениях Java 7, ICU и Perl "\x{1D11E}"необходимо использовать синтаксис ; аналогично, в ECMAScript 2015 (JavaScript) escape-формат равен "\u{1D11E}". Во многих других случаях (например, Java вне регулярных выражений) [25]единственный способ получить символы, отличные от BMP, - ввести суррогатные половинки по отдельности, например: "\uD834\uDD1E"для U + 1D11E.

Реализации строк, основанные на UTF-16, обычно определяют длину строки и позволяют индексацию в терминах этих 16-битных кодовых единиц , а не в терминах кодовых точек. Ни кодовые точки, ни кодовые единицы не соответствуют чему-либо, что конечный пользователь мог бы распознать как «символ»; то, что пользователи идентифицируют как символы, обычно может состоять из базовой кодовой точки и последовательности комбинируемых символов (или может быть последовательностью кодовых точек какого-либо другого типа, например, хангыль, соединяющий джамос) - Unicode называет эту конструкцию графемой cluster [26]  - и поэтому приложения, работающие со строками Unicode, независимо от кодировки, должны справляться с тем фактом, что это ограничивает их способность произвольно разбивать и комбинировать строки.

UCS-2 также поддерживается языком PHP [27] и MySQL. [7]

Swift версии 5, предпочтительный язык приложений Apple, переключился с UTF-16 на UTF-8 в качестве предпочтительной кодировки. [28]

См. Также [ править ]

  • Сравнение кодировок Unicode
  • Самолет (Unicode)
  • UTF-8
  • UTF-32

Примечания [ править ]

  1. ^ Кодировка UTF-8 дает байтовые значения строго меньше 0xFE, поэтому любой байт в последовательности спецификации также идентифицирует кодировку как UTF-16 (при условии, что UTF-32 не ожидается).
  2. ^ Использование U + FEFF в качестве символа ZWNBSP вместо BOM устарело в пользу U + 2060 (WORD JOINER); см. FAQ по метке порядка байтов (BOM) на unicode.org. Но если приложение интерпретирует исходную спецификацию как символ, символ ZWNBSP невидим, поэтому влияние минимально.
  3. ^ В разделе 4.3 RFC 2781 говорится, что если нет спецификации, «текст ДОЛЖЕН интерпретироваться как прямой порядок байтов». Согласно разделу 1.2, значение термина «ДОЛЖНО» регулируется RFC 2119 . В этом документе в разделе 3 говорится: «... при определенных обстоятельствах могут существовать веские причины для игнорирования конкретного пункта, но все последствия должны быть поняты и тщательно взвешены, прежде чем выбирать другой курс».  

Ссылки [ править ]

  1. ^ a b "Что такое UTF-16?" . Консорциум Unicode . Unicode, Inc . Проверено 29 марта 2018 .
  2. ^ a b «Используйте кодовую страницу Windows UTF-8 - приложения UWP» . docs.microsoft.com . Проверено 6 июня 2020 . Начиная с версии Windows 1903 (обновление за май 2019 г.), вы можете использовать свойство ActiveCodePage в appxmanifest для упакованных приложений или манифест слияния для неупакованных приложений, чтобы заставить процесс использовать UTF-8 в качестве кодовой страницы процесса. [..] соответствует только при работе в Windows версии 1903 (обновление за май 2019 г.) или выше, а для свойства ActiveCodePage, описанного выше, задано значение UTF-8. В противном случае учитывается устаревшая системная кодовая страница. Мы рекомендуем использовать явно.CP_ACPCP_UTF8CP_UTF8
  3. ^ «Уровень жизни HTML» . w3.org . 2020-06-10 . Проверено 15 июня 2020 . Кодировки UTF-16 - единственные кодировки, которые эта спецификация должна рассматривать как несовместимые с ASCII.
  4. ^ «Статистика использования UTF-16 для веб-сайтов, апрель 2018 г.» . w3techs.com . Проверено 11 апреля 2018 .
  5. ^ «Статистика использования UTF-8 для веб-сайтов, июнь 2020 г.» . w3techs.com . Проверено 1 августа 2020 .
  6. ^ «Стандарт кодирования» . encoding.spec.whatwg.org . Проверено 22 октября 2018 . Кодировка UTF-8 является наиболее подходящей кодировкой для обмена Unicode, универсальным набором кодированных символов. Поэтому для новых протоколов и форматов, а также для существующих форматов, развернутых в новых контекстах, эта спецификация требует (и определяет) кодировку UTF-8. [..] Проблемы, описанные здесь, исчезают при использовании исключительно UTF-8, что является одной из многих причин, по которым UTF-8 теперь является обязательной кодировкой для всех текстовых вещей в Интернете.
  7. ^ a b «Справочное руководство MySQL :: MySQL 5.7 :: 10.1.9.4 Набор символов ucs2 (кодировка Unicode UCS-2)» . dev.mysql.com .
  8. ^ «Вопросы по кодировке форм» . Проверено 12 ноября 2010 .
  9. ^ ISO / IEC 10646: 2014 «Информационные технологии - Универсальный набор кодированных символов (UCS)», разделы 9 и 10.
  10. ^ Стандарт Unicode версии 7.0 (2014) раздел 2.5.
  11. ^ «Версия 10.0 стандарта Unicode® - Основная спецификация. Приложение C Отношение к ISO / IEC 10646» (PDF) . Консорциум Unicode. раздел C.2 стр. 913 (pdf стр. 10)
  12. ^ «Политика стабильности кодировки символов Unicode» . unicode.org .
  13. ^ Йерго, Франсуа; Хоффман, Пол. «UTF-16, кодировка ISO 10646» . tools.ietf.org . Проверено 18 июня 2019 .
  14. ^ Аллен, Джули Д .; Андерсон, Дебора; Беккер, Джо ; Кук, Ричард, ред. (2014). «3.8 Суррогаты» (PDF) . Стандарт Unicode, версия 7.0 - основная спецификация . Маунтин-Вью: Консорциум Unicode . п. 118 . Дата обращения 3 ноября 2014 .
  15. ^ Юникод (Windows) . Проверено 08 марта 2011 г. «Эти функции используют кодировку UTF-16 (широкие символы) (…), используемую для собственной кодировки Unicode в операционных системах Windows».
  16. ^ «Описание хранения данных UTF-8 в SQL Server» . microsoft.com. 7 декабря 2005 . Проверено 1 февраля 2008 .
  17. ^ "Юникод" . microsoft.com . Проверено 20 июля 2009 .
  18. ^ «Суррогаты и дополнительные символы» . microsoft.com . Проверено 20 июля 2009 .
  19. ^ «UCS-2 и его отношение к Unicode (UTF-16)» . IBM . Проверено 26 апреля 2019 .
  20. ^ Селф, Чад (2012-11-08). «Приключения в Unicode SMS» . Twilio . Проверено 28 августа 2015 .
  21. ^ «PEP 261 - Поддержка« широких »символов Юникода» . Python.org . Проверено 29 мая 2015 .
  22. ^ «PEP 0393 - Гибкое представление строк» . Python.org . Проверено 29 мая 2015 .
  23. ^ "Внутренняя кодировка символов JavaScript: UCS-2 или UTF-16? · Матиас Биненс" .
  24. ^ «ECMA-334: 9.4.1 Управляющие последовательности Unicode» . en.csharp-online.net . Архивировано из оригинала на 2013-05-01.
  25. ^ Лексическая структура: Unicode Escapes в "Спецификации языка Java, третье издание" . Sun Microsystems, Inc . 2005 . Проверено 11 октября 2019 .
  26. ^ «Глоссарий терминов Unicode» . Проверено 21 июня 2016 .
  27. ^ «PHP: Поддерживаемые кодировки символов - Руководство» . php.net .
  28. ^ "Строка UTF-8" . Swift.org . 2019-03-20 . Проверено 20 августа 2020 .

Внешние ссылки [ править ]

  • Очень короткий алгоритм определения суррогатной пары для любой кодовой точки
  • Техническое примечание Unicode №12: UTF-16 для обработки
  • Вопросы и ответы по Unicode: в чем разница между UCS-2 и UTF-16?
  • Индекс имени символа Unicode
  • RFC 2781 : UTF-16, кодировка ISO 10646
  • документация java.lang.String, обсуждающая обработку суррогатов