В чем разница между UTF-8, UTF-16 и UTF-32?
Я понимаю, что все они будут хранить Unicode, и каждый из них использует другое количество байтов для представления символа. Есть ли преимущество в выборе одного над другим?
В чем разница между UTF-8, UTF-16 и UTF-32?
Я понимаю, что все они будут хранить Unicode, и каждый из них использует другое количество байтов для представления символа. Есть ли преимущество в выборе одного над другим?
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, 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.
Такой короткий ответ: все три кодировки могут кодировать один и тот же набор символов, но каждый символ представляет собой разные последовательности байтов.
Юникод - это стандарт, а о UTF-x вы можете рассматривать как техническую реализацию для некоторых практических целей:
Я попытался дать простое объяснение в blogpost.
требуется 32 бита (4 байта) для кодирования любого символа. Например, для представления кодовой точки символа "A" с использованием этой схемы вам нужно записать 65 в 32-битном двоичном номере:
00000000 00000000 00000000 01000001 (Big Endian)
Если вы подойдете ближе, вы заметите, что наиболее правые семь битов на самом деле являются одними и теми же битами при использовании схемы ASCII. Но поскольку UTF-32 является фиксированной схемой ширины, мы должны добавить три дополнительных байта. Это означает, что если у нас есть два файла, которые содержат только символ "A", один из них кодируется ASCII, а другой кодируется в кодировке UTF-32, их размер будет 1 байт и 4 байта соответственно.
Многие считают, что, поскольку 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 кодовая точка может быть представлена с использованием 32, 16, 24 или 8 бит, а в качестве системы UTF-16 эта система также является системой кодирования с переменной длиной.
Наконец, мы можем представить "A" так же, как мы представляем его, используя систему кодирования ASCII:
01001101
Рассмотрим китайскую букву "語" - ее кодировка UTF-8:
11101000 10101010 10011110
Пока его кодировка UTF-16 короче:
10001010 10011110
Чтобы понять представление и как его интерпретировать, посетите исходный пост.
Я провел несколько тестов для сравнения производительности базы данных между UTF-8 и UTF-16 в MySQL.
UTF-8 будет наиболее эффективным с точки зрения пространства, если большинство персонажей не будет находиться в пространстве символов CJK (китайский, японский и корейский).
UTF-32 лучше всего подходит для случайного доступа по смещению символов в байтовый массив.
В UTF-32 все символы кодируются 32 битами. Преимущество состоит в том, что вы можете легко вычислить длину строки. Недостатком является то, что для каждого символа ASCII вы тратите лишние три байта.
В UTF-8 символы имеют переменную длину, символы ASCII кодируются в один байт (восемь бит), большинство западных специальных символов кодируются либо в двух байтах, либо в трех байтах (например, это байты в байтах) и более экзотических символов может занимать до четырех байтов. Очевидным недостатком является то, что априорно вы не можете рассчитать длину строки. Но для кодирования латинского (английского) текста алфавита требуется намного меньше байтов, по сравнению с UTF-32.
UTF-16 также является переменной длиной. Символы кодируются либо в двух байтах, либо в четырех байтах. Я действительно не понимаю смысла. Он имеет недостаток в переменной длины, но не обладает тем преимуществом, что экономит столько места, сколько UTF-8.
Из этих трех, очевидно, UTF-8 является наиболее распространенным.
В зависимости от вашей среды разработки у вас может даже не быть выбора, как будет использоваться кодировка типа данных строки.
Но для хранения и обмена данными я всегда использовал UTF-8, если у вас есть выбор. Если у вас есть в основном данные ASCII, это даст вам наименьший объем данных для передачи, при этом все еще можно кодировать все. Оптимизация для наименьшего ввода-вывода - это способ работы на современных машинах.
Короче говоря, единственной причиной использования UTF-16 или UTF-32 является поддержка неанглийских и древних сценариев соответственно.
Мне было интересно, почему кто-то предпочел бы иметь кодировку, отличную от UTF-8, когда она, очевидно, более эффективна для веб-программирования.
Распространенное заблуждение - суффиксное число НЕ является показателем его возможностей. Все они поддерживают полный Unicode, только UTF-8 может обрабатывать ASCII с одним байтом, так что MORE эффективнее/менее коррумпирован для процессора и через Интернет.
Хорошее чтение: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html и http://utf8everywhere.org
Как уже упоминалось, разница состоит прежде всего в размере основных переменных, которые в каждом случае становятся больше, чтобы можно было представить больше символов.
Однако, шрифты, кодирование и вещи злобно сложны (излишне?), поэтому для более подробной информации требуется большая ссылка:
http://www.cs.tut.fi/~jkorpela/chars.html#ascii
Не ожидайте, что все это поймете, но если вы не хотите иметь проблемы позже, он стоит узнать как можно больше, как вы можете (или просто заставить кого-то еще разобраться в этом),
Павел.