Почему существует несколько кодировок Unicode?

41

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

Почему тогда так много кодировок Юникода? Даже несколько версий (по сути) одного и того же, как UTF-8, UTF-16 и т. Д.

Мэтью Шарли
источник
11
UTF-8 - это не то же самое, что UTF-16. Список будет расти, как только мы столкнемся с другими солнечными системами с планетами земного типа.
Сетзамора
1
@Joset: у нас уже есть клингон. У нас на БМП большинство земных языков с небольшим разливом на равнины 1,2. Если текущие теории верны и в галактике есть только 42 разумных вида, которые достигают точки, где они могут использовать космическое путешествие (таким образом, позволяют первый контакт), мы должны быть в состоянии сжать все символы на всех языках в ЮНИКОД (при условии, что мы можем расширить от 21 до 22 бит, чтобы разрешить 64 равнины). Это даже оставляет 10 бит буферного пространства, если мы хотим включить примитивные виды, которые не достигли космического полета.
Мартин Йорк
7
@Kevin Hsu: UTF-7,8,16LE, 16BE, 32LE, 32BE. Итак, существует как минимум 6 реальных кодировок. UTF-9 и UTF-18 - апрельские дураки.
MSalters
9
Хорошая вещь о стандартах в том, что их так много
Homde
1
Посмотрите, что Спольский говорил о Юникоде и кодировке .
MPelletier

Ответы:

29

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

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

Килиан Фот
источник
8
+1 Отличный ответ. Честно говоря, это единственный, кто действительно отвечает на этот вопрос. Все остальные ответы (более или менее) о том, как байты расположены во всех различных кодировках Unicode.
Яцек Прусия
Исторически это простой вопрос разногласий. Однако сегодня я не вижу особого смысла ни для чего, кроме UTF-8, хотя существуют теоретические сценарии, в которых UTF-16 будет занимать меньше места, это не слишком много, и они редки. Самым заметным местом, где вы хотели бы сэкономить место, являются веб-сайты, но они полны HTML-кодов, которые намного короче с использованием UTF-8. Например, вы можете использовать Shift JISяпонский веб-сайт меньше, чем эквивалент UTF-8, но это работает только потому, что это кодировка специально для японского языка.
аааааааааааа
2
Не совсем верно, либо. Поскольку сжатые форматы действительно используются только для транспортировки и хранения. В приложении чаще используется UCS-2 или UCS-4, поскольку они имеют фиксированную ширину, но занимают 2 или 4 байта на символ. Поэтому приложения готовы освободить пространство для простоты использования.
Мартин Йорк,
but it is less useful for European languages, and of little use for Asian languages- это просто неправильно. Под «полезностью» вы подразумеваете сжатие? Ну, тогда UTF-8 обеспечивает лучшее сжатие для европейских языков, потому что в каждом тексте есть пробелы и знаки препинания, которые занимают только один байт.
Волынкин
37

Unicode - это 21-битная кодировка символов, уникально описывающая «CodePoints», где каждая кодовая точка представлена ​​глифом (графическое представление).

  • 16 битов, используемых для идентификации кодовой точки на плоскости (большинство кодовых точек на плоскости 0).
  • 5 бит для определения плоскости.

Поддерживаемые кодировки:

  • UTF-8 (для кодирования каждой точки с использованием 8-битных значений)
  • UTF-16 (для кодирования каждой точки с использованием 16-битных значений)
  • UTF-32 (для кодирования каждой точки с использованием 32-битных значений)

Но независимо от кодировки, когда вы декодируете, все они отображаются обратно на конкретную кодовую точку, которая имеет одинаковое значение (вот почему это круто).

UTF-8,

Это формат переменного размера. Где каждая кодовая точка представлена ​​от 1 до 4 байтов.

UTF-16

Это формат переменного размера. Кодовые точки в «Базовой многоязычной плоскости» (BMP или Plane 0) могут быть представлены одним одиночным 16-битным значением. Кодовые точки в других плоскостях представлены суррогатной парой (2 16-битные значения).

UTF-32

Это формат с фиксированным размером. Все кодовые точки представлены одним 32-битным значением.

Мартин Йорк
источник
2
Мне тоже нравится этот ответ. Писал один похожий, но этот понятен. Я также добавил бы, что UTF-8 также полезен тем, что строки ASCII автоматически являются UTF-8.
Кевин Сюй
4
Пожалуйста, это базовая многоязычная плоскость , а не равнина .
JSB ձոգչ
3
Это хороший ответ, но я думаю, что он все еще напрашивается на вопрос «Почему?», Хотя этот ответ косвенно касается этого. Для уточнения: UTF-32 является более прямым (некоторые сказали бы более простым) подходом кодирования символов Unicode, но он также тратит много места, так как каждый символ занимает 4 байта. UTF-8 намного более компактен и обратно совместим с ASCII, но это не регулярно: символ может занимать от 1 до 4 байтов для кодирования, что затрудняет работу с ним. UTF-16 является своего рода гибридным подходом между двумя, в основном с за и против каждого.
Мипади
4
Существует компромисс между использованием памяти (где UTF-8 лучше, так как наиболее распространенные символы однобайтовые) и скоростью обработки (где UTF-32 лучше, потому что все символы имеют одинаковый размер, что обеспечивает определенную оптимизацию и дает идеальный 32-битное выравнивание в памяти). В результате сетевые протоколы и форматы файлов обычно используют UTF-8 (для экономии пропускной способности / места для хранения), в то время как интерпретаторы сценариев и языковые среды выполнения могут предпочитать UTF-16 или UTF-32.
tdammers
2
@Marcel: «CodePoint» - это не «CodePoint», а «a» character(так как символ может быть составлен из нескольких «CodePoints»). Не путайте два термина. Но вы правы: «CodePoints» не относятся к глифам. Глиф - это просто графическое представление кодовой точки. Тонкое, но важное отличие.
Мартин Йорк,
25

Я думаю, что полезно разделить 2 идеи:

  1. Unicode - отображение символов со всего мира на кодовые точки.
  2. Кодирование - отображение кодовых точек на битовые комбинации (UTF-8, UTF-16 и т. Д.).

UTF-8, UTF-16 и другие кодировки имеют свои преимущества и недостатки. Об этом лучше проконсультироваться в Википедии .

JFS
источник
@jfs: Зачем вообще нужен Юникод, если все еще будет дюжина или более разных кодировок, которые все равно будут отличаться в сети? Какая польза от использования глобального картирования?
Мэтью Шарли
10
@ Мэтью Шарли: Вы смотрите на это неправильно. UNICODE отображает все символы из всех языков (включая клингон) в уникальный идентификатор (кодовая точка). Кодировки - это просто способ сжатия кодовых точек на диск или поток по сети. UTF расшифровывается как «UNICODE Transport format». Вы всегда должны думать о кодовой точке UNICODE как о 21-битном значении. Преимущество перед другими форматами состоит в том, что все символы уникально идентифицированы и не перекрываются (в отличие от Latin-1, Latin-2 и т. Д.).
Мартин Йорк
@ Мэтью Шарли Зачем нужна глобальная картография? На самом деле каждый имел свое собственное отображение в прошлом (помните кодовые страницы?). Я думаю, что глупый пример прояснит ситуацию. Представьте себе идею любви. Как вы будете представлять это кому-то? Дарить цветы? Сказать я тебя люблю"? У каждого свой способ выразить это. Любовь (которая является абстрактной идеей) подобна кодовым точкам. Выражение это как кодировки. :)
JFS
4
Юникод это глобальный алфавит. UTF-x - это способ, которым он транспортируется компьютерами, поскольку трудно протолкнуть бумагу через провода.
Мел
1
@ Мартин, Клингон на самом деле не смог. Тенгвар или Кирит также не использовались для написания эльфийских языков Толкеина.
TRiG
9

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

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

Это сильно отличается от общей кодификации глифов в зависимости от страны, а иногда и от поставщика. В одном только японском языке было множество вариаций одного JIS, не говоря уже о EUC-JP и преобразовании JIS, ориентированном на кодовую страницу, которое использовали машины DOS / Windows, называемое Shift-JIS. (В некоторой степени они были алгоритмическими преобразованиями, но они не были особенно простыми, и существовали различия в зависимости от поставщиков в доступных символах. Умножьте это на пару сотен стран и постепенную эволюцию более сложных систем шрифтов (после «зеленого экрана») эра), и у вас был настоящий кошмар.

Зачем вам нужны эти формы преобразования Unicode? Поскольку во многих унаследованных системах использовались последовательности из 7-битных символов в диапазоне ASCII, вам нужно было 7-битное чистое решение для безопасной передачи данных через эти системы без искажений, поэтому вам понадобился UTF-7. Тогда были более современные системы, которые могли бы иметь дело с 8-битными наборами символов, но обычно нулевые значения имели для них особое значение, поэтому UTF-16 для них не работал. 2 байта могли закодировать всю базовую многоязычную плоскость Unicode в своем первом воплощении, поэтому UCS-2 казался разумным подходом для систем, которые собирались быть «осведомленными об Unicode с нуля» (например, Windows NT и Java VM); тогда расширения за этим требовали дополнительных символов, что привело к алгоритмическому преобразованию кодировок на 21 бит, которые были зарезервированы стандартом Unicode, и родились суррогатные пары; что потребовало UTF-16. Если у вас было какое-то приложение, в котором согласованность ширины символов была важнее, чем эффективность хранения, UTF-32 (когда-то назывался UCS-4) был вариантом.

UTF-16 - это единственная вещь, с которой трудно справиться, и это легко смягчается небольшим диапазоном символов, на которые влияет это преобразование, и тем фактом, что ведущие 16-битные последовательности находятся в совершенно отличном диапазоне от конечного 16-битные последовательности. Это также намного проще, чем пытаться двигаться вперед и назад во многих ранних восточноазиатских кодировках, где вам либо нужен конечный автомат (JIS и EUC) для работы с escape-последовательностями, либо потенциально вы можете вернуться назад на несколько символов, пока не найдете что-то гарантированное быть только ведущим байтом (Shift-JIS). UTF-16 имеет некоторые преимущества в системах, которые также могут эффективно передавать 16-битные последовательности.

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

JasonTrue
источник
1
Различные конечные автоматы JIS и EUC действительно противны, и вдвойне, если вы работаете с трансформацией между ними. Unicode значительно упрощает это. Единственная серьезная проблема с Unicode, что вы получили , чтобы перестать думать байты как символы, ASCII-используя небольшие символьный-выставиться шовинист вас!
Donal Fellows
6

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

Unicode был разработан, чтобы обойти всю проблему одного числа, представляющего много разных вещей в зависимости от используемой кодовой страницы. Числа 0 - 127 представляют одинаковые символы в любой кодовой странице Ansi. Это то, что также известно как диаграмма ASCII или набор символов. В кодовых страницах Ansi, которые допускают 256 символов, числа 128 - 255 представляют разные символы в разных кодовых страницах.

Например

  • Число $ 57 представляет собой заглавную букву W во всех кодовых страницах, но
  • Число $ EC представляет символ бесконечности на кодовой странице 437 (США), но "LATIN SMALL LETTER N WITH CEDILLA" на кодовой странице 775 (Балтика)
  • Знак Cent номер 9B на кодовой странице 437, а номер 96 на кодовой странице 775

То, что сделал Unicode, это перевернуло все это с ног на голову. В Unicode нет «повторного использования». Каждое число представляет один уникальный символ. Число $ 00A2 в Unicode - это знак цента, а знак цента больше нигде в определении Unicode.

Почему тогда так много кодировок Юникода? Даже несколько версий (по сути) одного и того же, как UTF-8, UTF-16 и т. Д.

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

Unicode определяет (или имеет пространство для определения) 4.294.967.295 уникальных символов. Если вы хотите сопоставить их с диском / памятью без каких-либо алгоритмических преобразований, вам нужно 4 байта на символ. Если вам нужно хранить тексты с символами из всех языковых плоскостей, то, вероятно, вам нужен UTF-32 (который представляет собой прямую 1-символьную 4-байтовую кодировку хранения определения Unicode).

Но вряд ли в каких-либо текстах используются символы всех языковых плоскостей. И тогда использование 4 байтов на символ кажется большой тратой. Особенно, если принять во внимание, что большинство языков на земле определены в рамках так называемой Базовой многоязычной плоскости (BMP): первые 65536 чисел определения Unicode.

И вот тут-то и появился UTF-16. Если вы используете только символы из BMP, UTF-16 будет очень эффективно хранить это, используя только два байта на символ. Он будет использовать больше байтов только для символов за пределами BMP. Различие между UTF-16LE (Little Endian) и UTF-16BE (Big Endian) действительно имеет отношение только к тому, как числа представляются в памяти компьютера (байтовый паттерн, A0означающий hex $ A0 или значение $ 0A).

Если ваш текст использует еще меньше разных символов, как большинство текстов на западноевропейских языках, вы захотите еще больше ограничить требования к хранению ваших текстов. Следовательно, UTF-8, который использует один байт для хранения символов, присутствующих в диаграмме ASCII (первые 128 чисел) и выбора из символов Ansi (вторые 128 чисел различных кодовых страниц). Он будет использовать только больше байтов для символов за пределами этого набора «наиболее часто используемых символов».

Итак, резюмируем:

  • Юникод - это отображение символов на всех языках мира (и некоторых клингонов для загрузки), а затем некоторых (математических, музыкальных и т. Д.) Уникальных чисел.
  • Кодировки - это алгоритмы, определенные для хранения текстов, использующих номера этой уникальной карты символов как можно более эффективно, учитывая «среднее использование» символов в текстах.
Марьян Венема
источник
2
«Числа 0 - 127 обозначают одинаковые символы в любой кодовой странице». - ну, если вы не говорите EBCDIC, в этом случае $57не W
MSalters
@MSalters: вы абсолютно правы. EBCDIC отличается (и есть другие EBCDIC). Я думаю, что мои дни в мэйнфреймах так долго позади, что я не помню, или я подавил эти воспоминания слишком сильно и слишком долго ... :-)
Marjan Venema
«Числа 0 - 127 обозначают одинаковые символы в любой кодовой странице». На самом деле существуют кодировки, такие как BinarySignWriting, которые не являются надмножествами ASCII. BinarySignWriting, по сути, вообще не содержит символов ASCII.
TRiG
@TRiG: Вот почему я отредактировал свое заявление специально для кодовых страниц Ansi. Должно быть, это было до того, как вы освежились ...
Марьян Венема
Да. Был дополнительный комментарий и обновление поста, когда я писал свой комментарий. Тем не менее, BinarySignWriting интересно.
TRiG
2

Юникод определяет карту между числами и символами. Однако, когда вы отправляете номер получателю, вам все равно нужно определить, как представлять этот номер. Вот для чего нужен UTF. Он определяет, как представлять число в потоке байтов.

Codism
источник
2

Смысл UTF-32 прост: это самое простое представление кодовых точек Unicode. Так почему же не все в UTF-32? Две основные причины:

Одним из них является размер . UTF-32 требует 4 байта для каждого символа. Для текста, который использует только символы в основном многоязычном месте, это вдвое больше места, чем в UTF-16. Для английского текста это в 4 раза больше места, чем US-ASCII.

Главная причина - обратная совместимость . Каждая кодировка Unicode, отличная от «некодированной» UTF-32, была разработана для обратной совместимости с предшествующим стандартом.

  • UTF-8: обратная совместимость с US-ASCII.
  • UTF-16: обратная совместимость с UCS-2 (16-битный Unicode до того, как он был расширен за пределы BMP).
  • UTF-7: обратная совместимость с не 8-битными чистыми почтовыми серверами.
  • GB18030: обратная совместимость с кодировками GB2312 и GBK для китайского языка.
  • UTF-EBCDIC: обратная совместимость с базовым латинским подмножеством EBCDIC.

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

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

dan04
источник
1

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

Алгоритм архивирования на самом деле имеет несколько различных алгоритмов с различными характеристиками на выбор: сохраненный (без сжатия), сжатый, уменьшенный (методы 1-4), имплозированный, токенизированный, дефлированный, Deflate64, BZIP2, LZMA (EFS), WavPack, PPMd, где он теоретически может попробовать все из них и выбрать лучший результат, но обычно просто пойти с дефлированным.

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


источник
Шёрн: Разница с zip-файлом заключается в том, что есть заголовок, который сообщает вам, какое сжатие действует. С текстовыми файлами нам все еще нужно угадать, не так ли?
Мэтью Шарли
Существует специальная последовательность, которая говорит именно это. Из-за обратной совместимости с ASCII это необязательно.