Отличаются ли UTF-8, UTF-16 и UTF-32 количеством символов, которые они могут хранить?

ОК. Я знаю, что это выглядит как типичный

6 ответов


нет, это просто разные методы кодирования. Все они поддерживают кодирование одного и того же набора символов.

UTF-8 использует от одного до четырех байтов на символ в зависимости от того, какой символ вы кодируете. Символы в диапазоне ASCII занимают только один байт, в то время как очень необычные символы занимают четыре.

UTF-32 использует четыре байта на символ независимо от того, какой это символ, поэтому он всегда будет использовать больше места, чем UTF-8 для кодирования той же строки. Единственный преимущество заключается в том, что вы можете вычислить количество символов в строке UTF-32, только подсчитывая байты.

UTF-16 использует два байта для большинства символов, четыре байта для необычных.

http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings


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

UTF-8

UTF-8-это код переменной длины. Некоторые символы требуют 1 байт, некоторые требуют 2, Некоторые 3 и некоторые 4. Байты для каждого символа просто записываются один за другим как непрерывный поток байтов.

в то время как некоторые символы UTF-8 могут быть длиной 4 байта, UTF-8 невозможно закодировать 2^32 символа. Это даже не близко. Я попытаюсь объяснить причины этого.

программное обеспечение, которое читает поток UTF-8, просто получает последовательность байтов - как оно должно решить, следующие 4 байта-это один 4-байтовый символ, или два 2-байтовых символа, или четыре 1-байтовых символа (или какая-то другая комбинация)? В основном это делается путем решения, что определенные 1-байтовые последовательности не являются допустимыми символами, а некоторые 2-байтовые последовательности не являются допустимыми символами и т. д. Когда эти недопустимые последовательности появляются, предполагается, что они являются частью больше последовательности.

вы видели совсем другой пример этого, я уверен: это называется побегом. Во многом языки программирования решено, что \ символ в исходном коде строки не переводится на любой допустимый символ в "скомпилированной" форме строки. Когда \ находится в источнике, предполагается, что он является частью более длинной последовательности, например \n или \xFF. Обратите внимание, что \x является недопустимой 2-символьной последовательностью и \xF является недопустимой 3-символьной последовательностью, но \xFF является допустимой 4-символьной последовательностью.

в основном, есть компромисс между наличием многих характеры и иметь более короткие характеры. Если вы хотите 2^32 символов, они должны быть в среднем длиной 4 байта. Если вы хотите, чтобы все ваши символы были 2 байта или меньше, то вы не можете иметь более 2^16 символов. UTF-8 дает разумный компромисс: все ASCII символы (ASCII от 0 до 127) даны 1-байтовые представления, что отлично подходит для совместимости, но разрешено гораздо больше символов.

как и большинство кодировок переменной длины, включая виды побега последовательности, показанные выше, UTF-8 является мгновенная код. Это означает, что декодер просто читает байт за байтом, и как только он достигает последнего байта символа ,он знает, что такое символ (и он знает, что это не начало более длинного символа).

например, символ " A " представлен с использованием байта 65, и нет двух/трех/четырехбайтовых символов, первый байт которых равен 65. Иначе декодер не смог бы сказать. эти символы, кроме "А", за которыми следует что-то еще.

но UTF-8 ограничен еще больше. Это гарантирует, что кодировка более короткого символа никогда не появится в любом месте в кодировке более длинного символа. Например, ни один из байтов в 4-байтовом символе не может быть 65.

поскольку UTF-8 имеет 128 различных 1-байтовых символов (значения которых равны 0-127), все 2, 3 и 4-байтовые символы должны состоять исключительно из байтов в диапазоне 128-256. Это большое ограничение. Однако он позволяет строковым функциям, ориентированным на байты, работать практически без изменений. Например, C strstr() функция всегда работает так, как ожидалось, если ее входы являются допустимыми строками UTF-8.

UTF-16

UTF-16 также является кодом переменной длины; его символы потребляют либо 2, либо 4 байта. 2-байтовые значения в диапазоне 0xD800-0xDFFF зарезервированы для построения 4-байтовых символов, и все 4-байтовые символы состоят из два байта в диапазоне 0xD800-0xDBFF, а затем 2 байта в диапазоне 0xDC00-0xDFFF. По этой причине Unicode не назначает никаких символов в диапазоне U+D800-U+DFFF.

UTF-32

UTF-32-это код фиксированной длины, каждый символ имеет длину 4 байта. Хотя это позволяет кодировать 2^32 разных символа, в этой схеме разрешены только значения между 0 и 0x10FFFF.

емкость сравнение:

  • UTF-8: 2,097,152 (на самом деле 2,166,912, но из-за деталей дизайна некоторые из них сопоставляются с тем же самым)
  • UTF-16: 1,112,064
  • UTF-32: 4,294,967,296 (но ограничивается первым 1,114,112)

наиболее ограниченным является поэтому UTF-16! Формальное определение Юникода ограничило символы Юникода теми, которые могут быть закодированы с помощью UTF-16 (т. е. диапазон от U + 0000 до U+10FFFF без учета U+D800 до U+DFFF). UTF-8 и UTF-32 поддерживают все эти символы.

система UTF-8 фактически "искусственно" ограничена 4 байтами. Он может быть расширен до 8 байт без нарушения ограничений, которые я описал ранее, и это даст емкость 2^42. Исходная спецификация UTF-8 фактически допускала до 6 байт, что дает емкость 2^31. Но!--74-->RFC 3629 ограничил его 4 байтами, так как именно столько необходимо для покройте все, что делает UTF-16.

существуют другие (в основном исторические) схемы кодирования Unicode, в частности UCS-2 (который способен кодировать только U+0000 до U+FFFF).


UTF-8, UTF-16 и UTF-32 поддерживают полный набор кодовых точек unicode. Нет символов, которые поддерживаются одним, но не другим.

Что касается Бонусного вопроса " отличаются ли эти кодировки количеством символов, которые они могут быть расширены для поддержки?"И да, и нет. Способ кодирования UTF-8 и UTF-16 ограничивает общее количество кодовых точек, которые они могут поддерживать, менее чем 2^32. Однако консорциум Unicode не будет добавлять кодовые точки в UTF-32, которые не могут быть представлен в UTF-8 или UTF-16. Это нарушило бы дух стандартов кодирования и сделало невозможным гарантировать сопоставление один к одному от UTF-32 до UTF-8 (или UTF-16).


Я лично всегда проверяю Джоэл должности о unicode, кодировках и наборах символов, когда сомневаетесь.


все кодировки UTF-8/16/32 могут отображать все символы Юникода. См. сравнение Википедии кодировок Unicode.

эта статья IBM кодируйте XML-документы в UTF-8 очень полезно, и показывает если вы имеете выбор, то лучшее выбрать УТФ-8. Главным образом причины широкая поддержка инструмента, и УТФ-8 может обычно пройдите через системы, которые не знают unicode.

из раздела какие характеристики скажи на статья IBM:

и W3C и IETF имеют в последнее время стали более категоричны выбрав кодировку UTF-8 Во-первых, последний, и только иногда. Консорциум W3C характер Модель для Всемирной паутины 1.0: Основы гласит :" Когда уникальный требуется кодировка символов, кодировка должна быть UTF-8, UTF-16 или UTF-32. US-ASCII является вверх-совместимый с UTF-8 (an Строка US-ASCII также является UTF-8 строка, см. [RFC 3629]), и UTF-8 поэтому если совместимость с нами-ASCII-это необходимый." В практика, совместимость с нами-ASCII так полезно это почти требование. W3C мудро объясняет, "В других ситуациях, таких как APIs, UTF-16 или UTF-32 могут быть больше соответствующий. Возможные причины выбор одного из них включает эффективность внутренней обработки и взаимодействие с другими процессы."


как все уже говорили, UTF-8, UTF-16 и UTF-32 могут кодировать все кодовые точки Unicode. Однако вариант UCS-2 (иногда ошибочно называемый UCS-16) не может, и это тот, который вы найдете, например, в Windows XP / Vista.

посмотреть Википедия для получения дополнительной информации.

Edit: я ошибаюсь в Windows, NT был единственным, кто поддерживал UCS-2. Однако многие приложения Windows будут принимать одно слово в кодовой точке, как в UCS-2, поэтому вы, вероятно, найдете ошибки. См.еще одна статья в Википедии. (Спасибо JasonTrue)