UTF-8, UTF-16 и UTF-32


каковы различия между UTF-8, UTF-16 и UTF-32?

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

12 378

12 ответов:

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

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

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

короче:

  • 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: кодировка фиксированной ширины. Все кодовые точки занимают четыре байта. Огромный боров памяти,но быстро работать. Редко используемый.

in long: см. Wikipedia:UTF-8,UTF-16 и UTF-32.

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

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

  • UTF-32 исправлена 4 байт.

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

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

UTF-16 использует 16-бит по умолчанию, но это дает вам только 65k возможные символы, которых далеко не достаточно для полного набора 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-совместимым.

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

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

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

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

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

для того, чтобы понять представление и как оно интерпретируется, посетите оригинальный пост.

UTF-8

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

UTF-16

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

UTF-32

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

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

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

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

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

UTF-8

Enter image description here

UTF-16

Enter image description here

Вставить Скоростях

Enter image description here

Enter image description here

Скоростях Удалить

Enter image description here

Enter image description here

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

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

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

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

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

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

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

тем не менее, шрифты, кодировка и все остальное порочно сложны (излишне?), поэтому для более детального заполнения нужна большая ссылка:

http://www.cs.tut.fi/~jkorpela/chars. html#ascii

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

Павел.

короче говоря, единственная причина использовать UTF-16 или UTF-32-это поддержка неанглийских и древних скриптов соответственно.

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

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

хорошее чтение:http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html и http://utf8everywhere.org