stringtranslate.com

Сравнение кодировок Unicode

В этой статье сравниваются кодировки Unicode в двух типах сред: 8-битные чистые среды и среды, запрещающие использование байтовых значений с установленным старшим битом. Первоначально такие запреты допускали ссылки, которые использовали только семь бит данных, но они остаются в некоторых стандартах, и поэтому некоторое программное обеспечение, соответствующее стандартам, должно генерировать сообщения, которые соответствуют ограничениям. [ необходимо дополнительное объяснение ] Стандартная схема сжатия для Unicode и двоичное упорядоченное сжатие для Unicode исключены из сравнительных таблиц, поскольку сложно просто количественно оценить их размер.

Проблемы совместимости

Файл UTF-8 , содержащий только символы ASCII , идентичен файлу ASCII. Устаревшие программы, как правило, могут обрабатывать файлы в кодировке UTF-8, даже если они содержат символы, отличные от ASCII. Например, функция C printf может печатать строку UTF-8, поскольку она ищет только символ ASCII '%' для определения строки форматирования. Все остальные байты печатаются без изменений.

UTF-16 и UTF-32 несовместимы с файлами ASCII и, таким образом, требуют программ, поддерживающих Unicode , для их отображения, печати и обработки, даже если известно, что файл содержит только символы из подмножества ASCII. Поскольку они содержат много нулевых байтов, строки символов, представляющие такие файлы, не могут обрабатываться с помощью общей логики обработки строк с завершающим нулем . [a] Распространенность обработки строк с использованием этой логики означает, что даже в контексте систем UTF-16, таких как Windows и Java , текстовые файлы UTF-16 обычно не используются. Вместо этого по-прежнему используются старые 8-битные кодировки, такие как ASCII или ISO-8859-1 , полностью отказываясь от поддержки Unicode, или для Unicode используется UTF-8. [ необходима цитата ] Одним из редких контрпримеров является файл «strings», представленный в Mac OS X 10.3 Panther , который используется приложениями для поиска интернационализированных версий сообщений. По умолчанию этот файл закодирован в UTF-16, «работоспособность файлов, закодированных с использованием UTF-8, не гарантируется». [1]

XML традиционно кодируется как UTF-8, [ необходима ссылка ] и все процессоры XML должны как минимум поддерживать UTF-8 и UTF-16. [2]

Эффективность

UTF-8 требует 8, 16, 24 или 32 бита (от одного до четырех байтов ) для кодирования символа Unicode, UTF-16 требует 16 или 32 бита для кодирования символа, а UTF-32 всегда требует 32 бита для кодирования символа.

Первые 128 кодовых точек Unicode , U+0000 - U+007F, которые используются для элементов управления C0 и основных латинских символов и которые соответствуют ASCII, кодируются с использованием 8 бит в UTF-8, 16 бит в UTF-16 и 32 бит в UTF-32. Следующие 1920 символов, U+0080 - U+07FF, представляют собой остальные символы, используемые почти всеми латинскими алфавитами , а также греческим , кириллическим , коптским , армянским , ивритом , арабским , сирийским , таана и нко . Символы в этом диапазоне требуют 16 бит для кодирования как в UTF-8, так и в UTF-16 и 32 бита в UTF-32. Для символов от U+0800 до U+FFFF, оставшихся в базовой многоязыковой плоскости и способных представлять остальные символы большинства живых языков мира, в UTF-8 требуется 24 бита для кодирования символа, в то время как в UTF-16 требуется 16 бит, а в UTF-32 — 32. Кодовые точки от U+010000 до U+10FFFF, которые представляют символы в дополнительных плоскостях , требуют 32 бита в UTF-8, UTF-16 и UTF-32.

Файл короче в UTF-8, чем в UTF-16, если кодовых точек ASCII больше, чем кодовых точек в диапазоне от U+0800 до U+FFFF. Сторонники UTF-8 как предпочтительной формы утверждают, что реальные документы, написанные на языках, которые используют символы только в верхнем диапазоне, по-прежнему часто короче в UTF-8 из-за обширного использования пробелов, цифр, пунктуации, знаков новой строки, HTML и встроенных слов и аббревиатур, написанных латинскими буквами. [3] UTF-32, напротив, всегда длиннее, если только нет кодовых точек меньше U+10000.

Все печатные символы в UTF-EBCDIC используют по крайней мере столько же байтов, сколько и в UTF-8, а большинство используют больше, из-за решения, принятого для разрешения кодирования управляющих кодов C1 как отдельных байтов. Для семибитных сред UTF-7 более эффективен с точки зрения пространства, чем комбинация других кодировок Unicode с quoted-printable или base64 для почти всех типов текста [ необходимы дополнительные пояснения ] (см. «Семьбитные среды» ниже).

Время обработки

Текст с кодировкой переменной длины, такой как UTF-8 или UTF-16, сложнее обрабатывать, если необходимо работать с отдельными кодовыми единицами, а не с кодовыми точками. Поиск не зависит от того, имеют ли символы переменный размер, поскольку поиск последовательности кодовых единиц не заботится о разделах. Однако для этого требуется, чтобы кодировка была самосинхронизирующейся , каковыми являются и UTF-8, и UTF-16. Распространенное заблуждение заключается в том, что необходимо «найти n- й символ» и что для этого требуется кодировка фиксированной длины; однако при реальном использовании число n выводится только из проверки n−1 символов, поэтому последовательный доступ необходим в любом случае. [ необходима цитата ]

Эффективное использование последовательностей символов в одном порядке байтов , загруженных на машину с другим порядком байтов, требует дополнительной обработки. Символы могут быть либо преобразованы перед использованием, либо обработаны двумя различными системами. Байтовые кодировки, такие как UTF-8, не имеют этой проблемы. [ почему? ] UTF-16BE и UTF-32BE являются big-endian , UTF-16LE и UTF-32LE являются little-endian .

Проблемы с обработкой

Для обработки формат должен быть простым для поиска, усечения и, в целом, безопасно обрабатываться. [ необходима цитата ] Все обычные кодировки Unicode используют некоторую форму фиксированного размера кодовой единицы. В зависимости от формата и кодовой точки, которая должна быть закодирована, одна или несколько из этих кодовых единиц будут представлять кодовую точку Unicode . Чтобы обеспечить простой поиск и усечение, последовательность не должна встречаться внутри более длинной последовательности или на границе двух других последовательностей. UTF-8, UTF-16, UTF-32 и UTF-EBCDIC обладают этими важными свойствами, но UTF-7 и GB 18030 их не имеют.

Символы фиксированного размера могут быть полезны, но даже если есть фиксированное количество байтов на кодовую точку (как в UTF-32), нет фиксированного количества байтов на отображаемый символ из-за объединения символов . Учитывая эти несовместимости и другие особенности различных схем кодирования, обработка данных Unicode с помощью одного и того же (или совместимого) протокола во всех интерфейсах (например, использование API/библиотеки, обработка символов Unicode в модели клиент/сервер и т. д.) может в целом упростить весь конвейер, одновременно устраняя потенциальный источник ошибок.

UTF-16 популярен, поскольку многие API относятся к тому времени, когда Unicode имел фиксированную ширину 16 бит (называемый UCS-2). Однако использование UTF-16 делает символы за пределами базовой многоязыковой плоскости особым случаем, что увеличивает риск упущений, связанных с их обработкой. При этом программы, которые неправильно обрабатывают суррогатные пары, вероятно, также имеют проблемы с объединением последовательностей, поэтому использование UTF-32 вряд ли решит более общую проблему плохой обработки символов с несколькими кодовыми единицами.

Если какие-либо хранимые данные находятся в UTF-8 (например, содержимое или имена файлов), очень сложно написать систему, которая использует UTF-16 или UTF-32 в качестве API. Это связано с часто упускаемым из виду фактом, что байтовый массив, используемый UTF-8, может физически содержать недопустимые последовательности. Например, невозможно исправить недопустимое имя файла UTF-8 с помощью API UTF-16, поскольку никакая возможная строка UTF-16 не будет преобразована в это недопустимое имя файла. Обратное неверно: тривиально преобразовать недопустимый UTF-16 в уникальную (хотя технически недопустимую) строку UTF-8, поэтому API UTF-8 может управлять как файлами UTF-8, так и UTF-16 и именами, что делает UTF-8 предпочтительным в любой такой смешанной среде. К сожалению, гораздо более распространенным обходным решением, используемым системами UTF-16, является интерпретация UTF-8 как какой-то другой кодировки, например CP-1252 , и игнорирование моджибаке для любых данных, отличных от ASCII.

Для связи и хранения

UTF-16 и UTF-32 не имеют определенного порядка байтов , поэтому при их получении по байт-ориентированной сети или чтении из байт-ориентированного хранилища необходимо выбрать порядок байтов. Этого можно добиться, используя метку порядка байтов в начале текста или предполагая big-endian (RFC 2781). UTF-8 , UTF-16BE , UTF-32BE , UTF-16LE и UTF-32LE стандартизированы на одинарный порядок байтов и не имеют этой проблемы.

Если поток байтов подвержен повреждению, то некоторые кодировки восстанавливаются лучше, чем другие. UTF-8 и UTF-EBCDIC в этом отношении лучше всего, поскольку они всегда могут повторно синхронизироваться после поврежденного или отсутствующего байта в начале следующей кодовой точки; GB 18030 не может восстановиться до следующего нечислового символа ASCII. UTF-16 может обрабатывать измененные байты, но не нечетное количество отсутствующих байтов, что исказит весь последующий текст (хотя это приведет к появлению необычных и/или неназначенных символов). [b] Если биты могут быть потеряны, все они исказят последующий текст, хотя UTF-8 можно повторно синхронизировать, поскольку неверные границы байтов приведут к недействительному UTF-8 почти во всех текстах длиннее нескольких байтов.

Подробно

В таблицах ниже указано количество байтов на кодовую точку для различных диапазонов Unicode. Любые дополнительные комментарии, которые необходимо добавить, включены в таблицу. Цифры предполагают, что накладные расходы в начале и конце блока текста незначительны.

NB В таблицах ниже перечислены числа байтов на кодовую точку , а не на видимый пользователем "символ" (или "кластер графем"). Для описания одного кластера графем может потребоваться несколько кодовых точек, поэтому даже в UTF-32 следует соблюдать осторожность при разделении или конкатенации строк.

Восьмибитные среды

Семибитные среды

Эта таблица может не охватывать все особые случаи и поэтому должна использоваться только для оценки и сравнения. Чтобы точно определить размер текста в кодировке, см. фактические спецификации.

Порядок байтов не влияет на размер ( UTF-16BE и UTF-32BE имеют тот же размер, что и UTF-16LE и UTF-32LE соответственно). Использование UTF-32 в quote-printable крайне непрактично, но если его реализовать, то получится 8–12 байт на кодовую точку (в среднем около 10 байт), а именно для BMP каждая кодовая точка будет занимать ровно на 6 байт больше, чем тот же код в quote-printable/UTF-16. Base64/UTF-32 получает 5+13 байта для любой кодовой точки.

Управляющий символ ASCII в цитируемом-печатаемом или UTF-7 может быть представлен либо напрямую, либо закодирован (экранирован). Необходимость экранирования заданного управляющего символа зависит от многих обстоятельств, но новые строки в текстовых данных обычно кодируются напрямую.

Схемы сжатия

BOCU-1 и SCSU — это два способа сжатия данных Unicode. Их кодировка зависит от того, как часто используется текст. Большинство фрагментов текста используют один и тот же алфавит; например, латинский , кириллический , греческий и т. д. Такое обычное использование позволяет сжимать множество фрагментов текста примерно до 1 байта на кодовую точку. Эти кодировки с отслеживанием состояния затрудняют случайный доступ к тексту в любой позиции строки.

Эти две схемы сжатия не так эффективны, как другие схемы сжатия, такие как zip или bzip2 . Эти схемы сжатия общего назначения могут сжимать более длинные последовательности байтов всего до нескольких байтов. Схемы сжатия SCSU и BOCU-1 не сжимают более теоретических 25% текста, закодированного как UTF-8, UTF-16 или UTF-32. Другие схемы сжатия общего назначения могут легко сжимать до 10% от исходного размера текста. Схемы общего назначения требуют более сложных алгоритмов и более длинных фрагментов текста для хорошей степени сжатия.

Техническое примечание Unicode № 14 содержит более подробное сравнение схем сжатия.

Исторические: UTF-5 и UTF-6

Были сделаны предложения по UTF-5 и UTF-6 для интернационализации доменных имен (IDN). Предложение UTF-5 использовало кодировку с основанием 32 , где Punycode (помимо прочего, и не совсем) является кодировкой с основанием 36. Название UTF-5 для кодовой единицы из 5 бит объясняется уравнением 2 5 = 32. [4] Предложение UTF-6 добавило кодировку длины последовательности к UTF-5, здесь 6 просто означает UTF-5 плюс 1. [ 5] Рабочая группа IETF IDN позже приняла более эффективную Punycode для этой цели. [6]

Не преследуется всерьез

UTF-1 так и не получил серьезного признания. Гораздо чаще используется UTF-8.

Кодировки nonet UTF-9 и UTF-18 являются спецификациями RFC-шутки на День дурака , хотя UTF-9 является действующим форматом преобразования nonet Unicode, а UTF-18 является действующим кодированием nonet для всех кодовых точек, не относящихся к частному использованию, в Unicode 12 и ниже, хотя и не для дополнительных областей частного использования или частей Unicode 13 и выше .

Примечания

  1. ^ Программное обеспечение ASCII, не использующее нулевые символы для завершения строк, будет правильно обрабатывать файлы в кодировках UTF-16 и UTF-32 (такие файлы, если содержат только символы подмножества ASCII, будут отображаться как обычные ASCII, дополненные нулевыми символами ), но такое программное обеспечение не распространено. [ необходима ссылка ]
  2. ^ Напротив, четное число пропущенных байтов в UTF-16 приведет к искажению максимум одного символа.

Ссылки

  1. ^ «Apple Developer Connection: Темы программирования интернационализации: Файлы строк».
  2. ^ "Кодирование символов в сущностях". Extensible Markup Language (XML) 1.0 (пятое издание) . World Wide Web Consortium . 2008.
  3. ^ "UTF-8 Everywhere". utf8everywhere.org . Получено 28 августа 2022 г. .
  4. ^ Сенг, Джеймс, UTF-5, формат преобразования Unicode и ISO 10646, 28 января 2000 г.
  5. ^ Welter, Mark; Spolarich, Brian W. (16 ноября 2000 г.). "UTF-6 — еще одна кодировка, совместимая с ASCII, для идентификатора". Ietf Datatracker . Архивировано из оригинала 23 мая 2016 г. Получено 9 апреля 2016 г.
  6. ^ "Интернационализированное доменное имя (idn)". Internet Engineering Task Force . Получено 20 марта 2023 г.