В чем разница между UTF-8 и Unicode - PullRequest
430 голосов
/ 13 марта 2009

Я слышал противоречивые мнения людей - согласно странице Википедии UTF-8 .

Это одно и то же, не так ли? Может кто-нибудь уточнить?

Ответы [ 13 ]

434 голосов
/ 13 марта 2009

Чтобы расширить ответы, которые дали другие:

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

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

Старые кодировки символов, такие как ASCII, относятся к (до) 8-битной эре и пытаются втиснуть доминирующий язык в вычислениях того времени, то есть в английский, в числа в диапазоне от 0 до 127 (7 бит). С 26 буквами в алфавите, как в заглавной, так и в заглавной форме, цифры и знаки препинания работали довольно хорошо. ASCII расширился на 8 бит для других неанглийских языков, но дополнительные 128 цифр / кодовых точек, предоставляемые этим расширением, будут отображаться на разные символы в зависимости от отображаемого языка. Стандарты ISO-8859 являются наиболее распространенными формами этого картирования; ISO-8859-1 и ISO-8859-15 (также известные как ISO-Latin-1, latin1, и да, есть также две разные версии стандарта ISO 8859).

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

Существуют два разных типа кодирования: один расширяет диапазон значений, добавляя больше битов. Примерами этих кодировок могут быть UCS2 (2 байта = 16 бит) и UCS4 (4 байта = 32 бита). Они по своей природе страдают от той же проблемы, что и стандарты ASCII и ISO-8859, поскольку их диапазон значений по-прежнему ограничен, даже если этот предел значительно выше.

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

Многобайтовые кодировки (я должен сказать, несколько единиц после приведенного выше объяснения) имеют преимущество в том, что они относительно экономичны, но недостатком является то, что такие операции, как поиск подстрок, сравнения и т. Д., Все должны декодировать символы кодировать точки в кодировке Юникод до того, как такие операции могут быть выполнены (хотя есть некоторые сочетания клавиш).

Как стандарты UCS, так и стандарты UTF кодируют кодовые точки, как определено в Unicode. Теоретически, эти кодировки могут быть использованы для кодирования любого числа (в пределах диапазона, поддерживаемого кодировкой), но, конечно, эти кодировки были сделаны для кодирования кодовых точек Unicode. И это ваши отношения между ними.

Windows обрабатывает так называемые строки "Юникод" как строки UTF-16, в то время как большинство UNIX-систем по умолчанию используют UTF-8 в наши дни. Протоколы связи, такие как HTTP, как правило, лучше всего работают с UTF-8, поскольку размер блока в UTF-8 такой же, как в ASCII, и большинство таких протоколов были разработаны в эпоху ASCII. С другой стороны, UTF-16 обеспечивает наилучшую среднюю производительность пространства / обработки при представлении всех живых языков.

Стандарт Unicode определяет меньше кодовых точек, чем может быть представлено в 32 битах. Таким образом, для всех практических целей UTF-32 и UCS4 стали одной и той же кодировкой, поскольку вам вряд ли придется иметь дело с многозначными символами в UTF-32.

Надеюсь, что заполнит некоторые детали.

189 голосов
/ 13 марта 2009

К сожалению, «Unicode» используется по-разному в зависимости от контекста. Его наиболее правильное использование (IMO) - это набор кодированных символов , т. Е. Набор символов и отображение между символами и целыми кодовыми точками , представляющими их.

UTF-8 - кодировка символов - способ преобразования последовательностей байтов в последовательности символов и наоборот. Он охватывает весь набор символов Unicode. ASCII кодируется как один байт на символ, а другие символы занимают больше байтов в зависимости от их точной кодовой точки (до 4 байтов для всех определенных на данный момент кодовых точек, т. Е. До U-0010FFFF, и, действительно, 4 байта могут обрабатывать до U-001FFFFF).

Когда «Юникод» используется в качестве имени кодировки символов (например, в качестве свойства .NET Encoding.Unicode ), это обычно означает UTF-16 , который кодирует наиболее распространенную кодировку. символы в виде двух байтов. Некоторые платформы (особенно .NET и Java) используют UTF-16 в качестве «родной» кодировки символов. Это приводит к серьезным проблемам, если вам нужно беспокоиться о символах, которые не могут быть закодированы в одном значении UTF-16 (они закодированы как «суррогатные пары») - но большинство разработчиков никогда не беспокоятся об этом, IME.

Некоторые ссылки на Unicode:

181 голосов
/ 14 января 2015

Позвольте мне использовать пример, чтобы проиллюстрировать эту тему:

A chinese character:      汉
it's unicode value:       U+6C49
convert 6C49 to binary:   01101100 01001001

Пока ничего волшебного, все очень просто. Теперь, допустим, мы решили сохранить этого персонажа на нашем жестком диске. Для этого нам нужно сохранить символ в двоичном формате. Мы можем просто сохранить его как «01101100 01001001». Готово! * * 1004

Но подождите минуту, это «01101100 01001001» один символ или два символа? Вы знали, что это один из символов, потому что я сказал вам, но когда компьютер читает это, он понятия не имеет. Таким образом, нам нужно какое-то «кодирование», чтобы компьютер воспринимал его как единое целое.

Вот где вступают в действие правила UTF-8: http://www.fileformat.info/info/unicode/utf8.htm

Binary format of bytes in sequence

1st Byte    2nd Byte    3rd Byte    4th Byte    Number of Free Bits   Maximum Expressible Unicode Value
0xxxxxxx                                                7             007F hex (127)
110xxxxx    10xxxxxx                                (5+6)=11          07FF hex (2047)
1110xxxx    10xxxxxx    10xxxxxx                  (4+6+6)=16          FFFF hex (65535)
11110xxx    10xxxxxx    10xxxxxx    10xxxxxx    (3+6+6+6)=21          10FFFF hex (1,114,111)

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

Header  Place holder    Fill in our Binary   Result         
1110    xxxx            0110                 11100110
10      xxxxxx          110001               10110001
10      xxxxxx          001001               10001001

Вывод результата в одну строку:

11100110 10110001 10001001

Это UTF-8 (двоичное) значение китайского символа! (подтвердите сами: http://www.fileformat.info/info/unicode/char/6c49/index.htm)

Краткое описание

A chinese character:      汉
it's unicode value:       U+6C49
convert 6C49 to binary:   01101100 01001001
embed 6C49 as UTF-8:      11100110 10110001 10001001
107 голосов
/ 13 марта 2009

Это не одно и то же - UTF-8 - это особый способ кодирования Unicode.

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

60 голосов
/ 13 марта 2009

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

28 голосов
/ 24 февраля 2013

Unicode - это стандарт, который вместе с ISO / IEC 10646 определяет Универсальный набор символов (UCS) , который представляет собой расширенный набор всех существующих символов, необходимых для представления практически всех известных языков. .

Юникод назначает имя и номер ( код символа или кодовая точка ) каждому символу в своем репертуаре.

Кодировка UTF-8 - это способ цифрового представления этих символов в памяти компьютера. UTF-8 отображает каждую кодовую точку в последовательность октетов (8-битных байтов)

Например,

Символ UCS = Символ Юникод Хан

Кодовая точка UCS = U + 24B62

Кодировка UTF-8 = F0 A4 AD A2 (hex) = 11110000 10100100 10101101 10100010 (bin)

24 голосов
/ 13 марта 2009

Unicode - это просто стандарт, который определяет набор символов ( UCS ) и кодировки ( UTF ) для кодирования этого набора символов. Но в целом Unicode относится к набору символов, а не к стандарту.

Чтение Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (без оправданий!) и Unicode за 5 минут .

21 голосов
/ 19 мая 2014

Существующие ответы уже объясняют много деталей, но вот очень короткий ответ с самым прямым объяснением и примером.

Unicode - это стандарт , который отображает символы в кодовые точки.
Каждый символ имеет уникальный код (идентификационный номер), который представляет собой число, подобное 9731.

UTF-8 представляет собой кодировку кодовых точек.
Чтобы сохранить все символы на диске (в файле), UTF-8 разбивает символы на до 4 октетов (8-битных последовательностей) - байтов. UTF-8 - это одна из нескольких кодировок (методов представления данных). Например, в Unicode (десятичная) кодовая точка 9731 представляет снеговика (), который состоит из 3 байтов в UTF-8: E2 98 83

Вот отсортированный список с некоторыми случайными примерами .

14 голосов
/ 05 января 2015

1. Unicode

В мире много символов, таких как "$, &, h, a, t,?, 张, 1, =, + ...".

Затем появляется организация, которая посвящена этим персонажам,

Они сделали стандарт под названием «Юникод».

Стандарт выглядит следующим образом:

  • создать форму, в которой каждая позиция называется «кодовой точкой» или «кодовой позицией».
  • Целые позиции от U + 0000 до U + 10FFFF;
  • До сих пор некоторые позиции заполнены символами, а другие позиции сохраняются или остаются пустыми.
  • Например, позиция «U + 0024» заполнена символом «$».

PS: Конечно, есть другая организация, называемая ISO, поддерживающая другой стандарт - «ISO 10646» - почти такой же.

2. UTF-8

Как и выше, U + 0024 - это просто позиция, поэтому мы не можем сохранить «U + 0024» в компьютере для символа «$».

Должен быть метод кодирования.

Затем идут методы кодирования, такие как UTF-8, UTF-16, UTF-32, UCS-2 ....

В UTF-8 кодовая точка "U + 0024" кодируется в 00100100.

00100100 - это значение, которое мы сохраняем в компьютере для "$".

12 голосов
/ 30 мая 2011

Я проверил ссылки в ответе Гамбо, и я хотел вставить некоторую часть этих вещей, чтобы они также существовали в Переполнении стека.

"... Некоторые люди ошибочно полагают, что Unicode - это просто 16-битный код, в котором каждый символ занимает 16 бит и, следовательно, существует 65 536 возможных символов. Это, на самом деле, неверно. Это самый распространенный миф об Unicode, так что если вы так думаете, не расстраивайтесь.

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

До сих пор мы предполагали, что буква соответствует некоторым битам, которые вы можете сохранить на диске или в памяти:

A -> 0100 0001

В Юникоде буква отображается на то, что называется кодовой точкой, которая до сих пор является лишь теоретической концепцией. То, как эта кодовая точка представлена ​​в памяти или на диске, - это совсем другая история ... "

"... Каждой платонической букве в каждом алфавите консорциум Unicode присваивает магическое число, которое записывается так: U + 0639. Это магическое число называется кодовой точкой. U + означает" Unicode "и цифры шестнадцатеричные. U + 0639 - арабская буква Ain. Английская буква A будет U + 0041 .... "

"... Хорошо, скажем, у нас есть строка:

Hello

, что в Unicode соответствует этим пяти кодам:

U + 0048 U + 0065 U + 006C U + 006C U + 006F.

Просто куча кодов. Числа, правда. Мы еще ничего не сказали о том, как сохранить это в памяти или представить в сообщении электронной почты ... "

"... Вот где приходят кодировки.

Самой ранней идеей кодирования Unicode, которая привела к мифу о двух байтах, было, эй, давайте просто сохраним эти числа в двух байтах каждый. Так что Привет становится

00 48 00 65 00 6C 00 6C 00 6F

Правильно? Не так быстро! Разве это не может быть:

48 00 65 00 6C 00 6C 00 6F 00? ... "

...