UTF-8, UTF-16 и UTF-32 - PullRequest
       220

UTF-8, UTF-16 и UTF-32

436 голосов
/ 30 января 2009

В чем различия между UTF-8, UTF-16 и UTF-32?

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

Ответы [ 12 ]

329 голосов
/ 30 января 2009

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

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

UTF-32 будет охватывать все возможные символы в 4 байта. Это делает его довольно раздутым. Я не могу думать о каком-либо преимуществе его использования.

290 голосов
/ 30 января 2009

Короче говоря:

  • UTF-8: кодирование переменной ширины, обратно совместимое с ASCII. Символы ASCII (от U + 0000 до U + 007F) занимают 1 байт, кодовые точки от U + 0080 до U + 07FF занимают 2 байта, кодовые точки от U + 0800 до U + FFFF занимают 3 байта, кодовые точки от U + 10000 до U + 10FFFF взять 4 байта. Хорошо для английского текста, не очень хорошо для азиатского текста.
  • UTF-16: кодирование переменной ширины. Кодовые точки от U + 0000 до U + FFFF занимают 2 байта, кодовые точки от U + 10000 до U + 10FFFF занимают 4 байта. Плохо для английского текста, хорошо для азиатского текста.
  • UTF-32: кодирование с фиксированной шириной. Все кодовые точки занимают четыре байта. Огромная память, но быстро работать. Редко используется.

По длинне: см. Википедию: UTF-8 , UTF-16 и UTF-32 .

108 голосов
/ 30 января 2009
  • UTF-8 является переменной от 1 до 4 байтов.

  • UTF-16 является переменной 2 или 4 байтов.

  • UTF-32 фиксирован 4 байт.

74 голосов
/ 30 января 2009

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

Вкратце, UTF-32 использует 32-битные значения для каждого символа. Это позволяет им использовать код фиксированной ширины для каждого символа.

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

И UTF-8 по умолчанию использует 8-битные значения, что означает, что 127 первых значений являются однобайтовыми символами фиксированной ширины (старший бит используется для обозначения того, что это начало многобайтовой последовательности оставляя 7 битов для фактического значения символа). Все остальные символы кодируются как последовательности длиной до 4 байтов (если память служит).

И это приводит нас к преимуществам. Любой символ ASCII напрямую совместим с UTF-8, поэтому для обновления устаревших приложений UTF-8 является распространенным и очевидным выбором. Почти во всех случаях он также будет использовать наименьшее количество памяти. С другой стороны, вы не можете дать никаких гарантий относительно ширины символа. Ширина может быть 1, 2, 3 или 4 символа, что затрудняет манипулирование строками.

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

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

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

Linux немного отличается, но они обычно используют UTF-8 для всего, что соответствует Unicode.

Такой короткий ответ: все три кодировки могут кодировать один и тот же набор символов, но они представляют каждый символ как разные последовательности байтов.

40 голосов
/ 15 мая 2013

Unicode - это стандарт, а около UTF-x можно представить в качестве технической реализации для некоторых практических целей:

  • UTF-8 - " size optimized ": лучше всего подходит для данных на основе латинских символов (или ASCII), занимает всего 1 байт на символ, но размер увеличивается соответственно разнообразию символов (и в худшем случае может увеличиться до 6 байтов на символ)
  • UTF-16 - " balance ": требуется минимум 2 байта на символ, чего достаточно для существующего набора основных языков с фиксированным размером для упрощения обработки символов (но размер остается переменным и может увеличиваться до 4 байтов на символ)
  • UTF-32 - « производительность »: позволяет использовать простые алгоритмы как результат символов фиксированного размера (4 байта), но с недостатком памяти
20 голосов
/ 03 февраля 2016

Я попытался дать простое объяснение в моем блоге .

UTF-32

требуется 32 бита (4 байта) для кодирования любого символа. Например, чтобы представить кодовую точку символа «A» с помощью этой схемы, вам нужно написать 65 в 32-битном двоичном числе:

00000000 00000000 00000000 01000001 (Big Endian)

Если вы присмотритесь поближе, вы заметите, что при использовании схемы ASCII самые правые семь битов фактически являются одинаковыми. Но поскольку UTF-32 имеет схему фиксированной ширины , мы должны добавить три дополнительных байта. Это означает, что если у нас есть два файла, которые содержат только символ «A», один кодируется в кодировке ASCII, а другой - в кодировке UTF-32, их размер будет 1 байтом и 4 байтами соответственно.

UTF-16

Многие думают, что, поскольку UTF-32 использует фиксированную ширину 32 бита для представления кодовой точки, UTF-16 имеет фиксированную ширину 16 бит. НЕПРАВИЛЬНО!

В UTF-16 кодовая точка может быть представлена ​​либо в 16 битах, либо в 32 битах. Так что эта схема является системой кодирования переменной длины. В чем преимущество UTF-32? По крайней мере, для ASCII размер файлов не будет в 4 раза больше исходного (но все равно вдвое), поэтому мы все еще не совместимы с ASCII.

Поскольку 7-битных символов достаточно для представления символа «A», теперь мы можем использовать 2 байта вместо 4, как UTF-32. Это будет выглядеть так:

00000000 01000001

UTF-8

Вы правильно догадались. В UTF-8 кодовая точка может быть представлена ​​с использованием 32, 16, 24 или 8 битов, а в качестве системы UTF-16 она также является системой кодирования переменной длины.

Наконец, мы можем представить «A» так же, как мы представляем его с помощью системы кодирования ASCII:

01001101

Небольшой пример, когда UTF-16 на самом деле лучше, чем UTF-8:

Рассмотрим китайскую букву "語" - ее кодировка UTF-8:

11101000 10101010 10011110

Хотя его кодировка UTF-16 короче:

10001010 10011110

Чтобы понять представление и его интерпретацию, посетите исходный пост.

18 голосов
/ 05 марта 2015

UTF-8

  • не имеет понятия порядка байтов
  • использует от 1 до 4 байтов на символ
  • ASCII является совместимым подмножеством кодировки
  • полностью самосинхронизирующийся, например отброшенный байт из любой точки потока повредит не более одного символа
  • почти все европейские языки кодируются двумя байтами или менее на символ

UTF-16

  • должен быть проанализирован с известным порядком байтов или считыванием метки порядка байтов (BOM)
  • использует 2 или 4 байта на символ

UTF-32

  • каждый символ 4 байта
  • должен быть проанализирован с известным порядком байтов или считыванием метки порядка байтов (BOM)

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

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

13 голосов
/ 08 января 2013

Я провел несколько тестов для сравнения производительности базы данных между UTF-8 и UTF-16 в MySQL.

Скорости обновления

UTF-8

Enter image description here

UTF-16 * +1010 * Enter image description here Скорости вставки Enter image description here Enter image description here Удалить скорости Enter image description here Enter image description here

11 голосов
/ 30 января 2009

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

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

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

Из этих трех, очевидно, наиболее широко распространен UTF-8.

6 голосов
/ 30 января 2009

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

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

...