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

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

Проблемы совместимости [ править ]

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

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

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

По умолчанию XML кодируется как UTF-8, и все процессоры XML должны как минимум поддерживать UTF-8 (включая US-ASCII по определению) и 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, то есть оставшиеся символы в базовой многоязычной плоскости(BMP, плоскость 0, от U + 0000 до U + FFFF), который включает в себя остальные символы большинства живых языков мира, UTF-8 требует 24 бита для кодирования символа, тогда как UTF-16 требует 16 бит и UTF -32 требуется 32. Кодовые точки от U + 010000 до U + 10FFFF, которые представляют символы в дополнительных плоскостях (плоскости 1–16), требуют 32 бита в UTF-8, UTF-16 и UTF-32.

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

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

Каждый формат имеет свой набор преимуществ и недостатков в отношении эффективности хранения (и, следовательно, времени передачи) и эффективности обработки. Эффективность хранения зависит от того места в кодовом пространстве Unicode, из которого преимущественно происходят любые заданные текстовые символы. Поскольку блоки пространства кода Unicode организованы по набору символов (например, алфавиту / скрипту), эффективность хранения любого заданного текста эффективно зависит от алфавита / скрипта.используется для этого текста. Так, например, UTF-8 требует на один байт на символ меньше (8 против 16 бит), чем UTF-16 для 128 кодовых точек между U + 0000 и U + 007F, но требует на один байт на символ больше (24 против 16 битов). ) для 63 488 кодовых точек между U + 0800 и U + FFFF. Следовательно, если в диапазоне от U + 0000 до U + 007F больше символов, чем в диапазоне от U + 0800 до U + FFFF, тогда UTF-8 более эффективен, а если их меньше, то UTF-16 более эффективен. эффективный. Если счетчики равны, значит, они одинакового размера. Удивительным результатом является то, что реальные документы, написанные на языках, которые используют символы только в верхнем диапазоне, все еще часто короче в UTF-8 из-за широкого использования пробелов, цифр, знаков препинания, новой строки, разметки html и встроенных слов и аббревиатуры, написанные латинскими буквами. [цитата необходима ]

Время обработки [ править ]

Что касается времени обработки, текст с кодировкой переменной длины, такой как UTF-8 или UTF-16, труднее обрабатывать, если есть необходимость найти отдельные единицы кода, в отличие от работы с последовательностями единиц кода. На поиск не влияет то, имеют ли символы переменный размер, поскольку поиск последовательности кодовых единиц не заботится о делениях (для этого требуется, чтобы кодировка была самосинхронизирующейся, каковой является как UTF-8, так и UTF-16). Распространенное заблуждение состоит в том, что существует необходимость «найти n- й символ» и что для этого требуется кодирование фиксированной длины; однако на практике число n получается только из проверки n-1 символов, поэтому в любом случае необходим последовательный доступ. [ необходима цитата] UTF-16BE и UTF-32BE являются прямым порядком байтов , UTF-16LE и UTF-32LE - прямым порядком байтов . Когда последовательности символов в одном порядке байтов загружаются на машину с другим порядком байтов, символы необходимо преобразовать, прежде чем их можно будет эффективно обрабатывать, если только данные не обрабатываются с байтовой гранулярностью (как требуется для UTF-8). Соответственно, рассматриваемая проблема больше относится к протоколу и связи, чем к вычислительной сложности.

Проблемы с обработкой [ править ]

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

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

UTF-16 популярен, потому что многие API относятся ко времени, когда Unicode был 16-битной фиксированной шириной. Однако использование 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, и игнорироватьmojibake для любых данных, отличных от ASCII.

Для связи и хранения [ править ]

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

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

Подробно [ править ]

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

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

Восьмибитные среды [ править ]

Семибитные среды [ править ]

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

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

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

Схемы сжатия [ править ]

BOCU-1 и ГТС два способ сжатия данных 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 использовало кодировку base 32 , где Punycode (среди прочего, но не совсем) является кодировкой base 36 . Название UTF-5 для 5-битной кодовой единицы объясняется уравнением 2 5 = 32. [3] Предложение UTF-6 добавило кодировку длины беговой строки в UTF-5, здесь 6 просто означает UTF-5 плюс 1. . [4] Группа IETF IDN WG позже приняла для этой цели более эффективный Punycode . [5]

Не преследуются серьезно [ править ]

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

UTF-9 и UTF-18 , несмотря на то, что они являются функциональными кодировками, были спецификациями шутки RFC Первого апреля .

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

  1. ^ Подключение разработчика Apple: Темы программирования интернационализации: файлы строк
  2. ^ «Кодировка символов в сущностях» . Расширяемый язык разметки (XML) 1.0 (пятое издание) . W3C . 2008 г.
  3. ^ Сенг, Джеймс, UTF-5, формат преобразования Unicode и ISO 10646 , 28 января 2000 г.
  4. ^ Велтер, Марк; Сполярич, Брайан В. (16 ноября 2000 г.). «UTF-6 - еще одна ASCII-совместимая кодировка для ID» . Инженерная группа Интернета . Архивировано 23 мая 2016 года . Проверено 9 апреля +2016 .
  5. ^ Историческая страница IETF IDN WG