Чому існує декілька кодувань Unicode?


41

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

Чому тоді так багато кодувань Unicode? Навіть кілька версій (по суті) одного і того ж, як UTF-8, UTF-16 тощо.


11
UTF-8 не є тим самим, що UTF-16. Список зростатиме, як тільки ми зустрінемо інші сонячні системи із земляними планетами.
сетзамора

1
@Joset: У нас вже є клінгон. У нас на БМП більшість мов землі з незначним розливом на рівнини 1,2. Якщо поточні теорії є правильними і в галактиці є лише 42 чутливі види, які досягають точки, коли вони можуть використовувати космічні подорожі (таким чином дозволяючи перший контакт), ми повинні мати можливість видавити всіх символів на всіх мовах до UNICODE (припускаючи, що ми можемо розширити від 21 до 22 біт, щоб дозволити 64 рівнини). Це навіть залишає 10 біт буферного простору, якщо ми хочемо включити примітивні види, які не досягли космічного польоту.
Мартін Йорк

7
@Kevin Hsu: UTF-7,8,16LE, 16BE, 32LE, 32BE. Отже, існує щонайменше 6 реальних кодувань. UTF-9 і UTF-18 - квітневі дурні.
MSalters

9
Хороша річ у стандартах полягає в тому, що їх так багато
Хомда

1
Подивіться, що Спольський мав сказати про Unicode та кодування .
MPelletier

Відповіді:


29

Тому що люди не хочуть витрачати 21 біт на кожен символ. У всіх сучасних системах це по суті означатиме використання трьох байтів на символ, що втричі більше, ніж звикли люди, тому вони взагалі не бажали приймати Unicode. Компроміси потрібно було знайти: наприклад, UTF-8 чудово підходить для англійського тексту, оскільки застарілі файли ASCII взагалі не потрібно конвертувати, але він є менш корисним для європейських мов і мало корисний для азіатських мов.

Так, в основному, так, ми могли б визначити як єдине універсальне кодування, так і єдину універсальну діаграму символів, але ринок не прийняв би його.


8
+1 Відмінна відповідь. Якщо бути по-справжньому чесним, це єдиний, хто реально відповідає на це питання. Всі інші відповіді - це (більш-менш) про те, як байти розкладені у всіх різних кодировках Unicode.
Яцек Прусія

Історично це проста проблема незгоди. Однак сьогодні я не бачу великої користі ні для чого, крім UTF-8, хоча є теоретичні сценарії, коли UTF-16 забирає менше місця, це не за великим запасом, і вони рідкісні. Найбільш помітне місце, де ви хочете заощадити місце, - це веб-сайти, але вони переповнені HTML-кодами, які на сьогоднішній день є найкоротшими за допомогою UTF-8. Наприклад, ви можете використовувати Shift JISдля того, щоб зробити японський веб-сайт меншим за еквівалент UTF-8, але це працює лише тому, що це шафа спеціально для японців.
aaaaaaaaaaaa

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 або площині 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 - це свого роду гібридний підхід між ними, здебільшого з плюсами і мінусами кожного.
mipadi

4
Існує компроміс між використанням пам'яті (де UTF-8 найкращий, оскільки найпоширеніші символи є однобайтовими) та швидкістю обробки (де UTF-32 найкращий, тому що всі символи однакового розміру, що дозволяє певні оптимізації та дає ідеальне 32-бітове вирівнювання в пам'яті). Як результат, мережеві протоколи та формати файлів зазвичай використовують UTF-8 (для економії пропускної здатності / місця для зберігання), тоді як інтерпретатори сценаріїв та мовні умови роботи можуть віддавати перевагу UTF-16 або UTF-32.
tdammers

2
@Marcel: "CodePoint" - це "CodePoint", а не a character(оскільки символ може бути побудований з декількох "CodePoints"). Не плутайте два терміни. Але ви правильні, "CodePoints" не стосуються гліфів. Гліф - це просто графічне зображення кодової точки. Тонка, але важлива відмінність.
Мартін Йорк

25

Я думаю, що корисно відокремити дві ідеї:

  1. Unicode - відображення символів з усього світу в кодових точках.
  2. Кодування - відображення точок коду до бітових шаблонів (UTF-8, UTF-16 тощо).

Кодування UTF-8, UTF-16 та інші мають свої переваги та недоліки. Краще проконсультуйтеся з цього приводу у Вікіпедії .


@jfs: Навіщо взагалі мати Unicode, хоча якщо все ще буде десяток чи більше різних кодувань, які все-таки різняться на дроті? Яку користь має глобальне картографування саме по собі?
Меттью Шарлі

10
@Matthew Scharley: Ви дивитесь на це неправильно. UNICODE карта всіх символів з усіх мов (включаючи Klingon) до UNIQUE ID (кодова точка). Кодування - це лише спосіб стиснення кодових точок на диск або потік через мережу. UTF означає "Транспортний формат UNICODE". Ви завжди повинні думати про кодову точку UNICODE як 21-бітове значення. Перевага перед іншими форматами полягає в тому, що всі символи є однозначно ідентифікованими та не перетинаються (на відміну від Latin-1, Latin-2 тощо).
Мартін Йорк

@Matthew Scharley Чому глобальне відображення? Насправді кожен мав своє власне відображення у минулому (пам'ятаєте кодові сторінки?). Я думаю, що дурний приклад очистить речі. Уявіть ідею кохання. Як ви будете представляти це комусь? Подарувати квіти? Скажіть "я тебе люблю"? У кожного свій спосіб вираження. Любов (яка є абстрактною ідеєю) схожа на кодові точки. Вираження це схоже на кодування. :)
jfs

4
Unicode - це глобальний алфавіт. UTF-x - це спосіб, яким він транспортується за допомогою комп’ютерів, оскільки важко просунути папір по дротах.
Мел

1
@Martin, Клінгон насправді не встиг. Також не використовували тенгвар чи цирит, які використовували для написання ельфійських язиків Толкейна.
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) для боротьби з послідовностями втечі, або потенційно переміщувати кілька символів, поки ви не знайдете щось гарантоване бути лише провідним байтом (Shift-JIS). UTF-16 також мав деякі переваги в системах, які могли ефективно проконтролювати 16-бітові послідовності.

Якщо б вам не довелося пережити десятки (сотні, справді) різних кодувань там, або не довелося будувати системи, що підтримують кілька мов у різних кодуваннях, іноді навіть в одному документі (як WorldScript у старих версіях MacOs), ви можете подумати форматів перетворення унікоду як непотрібної складності. Але це різке зниження складності в порівнянні з попередніми альтернативами, і кожен формат вирішує реальну технічну обмеженість. Вони також дуже ефективно конвертуються між собою, не вимагаючи складних таблиць пошуку.


1
Різні державні машини JIS та EUC справді неприємні, і вдвічі, якщо ви працюєте з трансформацією між ними. Unicode дуже спрощує це. Єдина серйозна проблема з Unicode, що ви отримали , щоб перестати думати байти як символи, ASCII-використовуючи невеликі символьний-виставитися шовініст вас!
Стипендіати Дональда

6

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

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

Наприклад

  • Число 57 доларів представляє велику величину W на всіх кодових сторінках, але
  • Число $ EC позначає символ нескінченності на кодовій сторінці 437 (США), а "ЛАТИННИЙ МАЛИЙ ПІСНЕННЯ N С CEDILLA" на кодовій сторінці 775 (Балтія)
  • Знак Cent - це номер $ 9B на кодовій сторінці 437, але номер 96 на сторінці коду 775

Що зробив Unicode, це перевернути все це догори ногами. У Unicode немає "повторного використання". Кожне число являє собою єдиний унікальний символ. Число $ 00A2 у Unicode - це знак цент, а знак цент не з’являється більше ніде у визначенні 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 номерів різних сторінок коду). Він використовуватиме лише більше байтів для символів поза цим набором "найбільш використовуваних символів".

Отже, резюмувати:

  • Unicode - це відображення символів на всіх мовах на землі (і деяких клінгонських для завантаження), а потім деяких (математичних, музичних тощо) на унікальне число.
  • Кодування - це алгоритми, визначені для зберігання текстів, використовуючи номери цієї унікальної карти символів якнайбільше простору, враховуючи "середнє використання" символів у текстах.

2
"Числа 0 - 127 представляють однакові символи на будь-якій сторінці коду." - ну, якщо ви не говорите про EBCDIC, то в цьому випадку $57це не W
MSalters

@MSalters: ви абсолютно праві. EBCDIC відрізняється (і є інші EBCDIC). Я здогадуюсь, що в мене основні дні настільки довгі за мною, що я не пам’ятав, або я придушив ці спогади занадто сильно і занадто довго ... :-)
Marjan Venema

"Числа 0 - 127 представляють однакові символи на будь-якій сторінці коду." Насправді є кодування, такі як BinarySignWriting, які не є набором ASCII. Фактично BinarySignWriting взагалі не містить жодних символів ASCII.
TRiG

@TRiG: Тому я редагував свою заяву, зокрема про кодові сторінки Ansi. Ви повинні зробити це, перш ніж освіжитися ...
Мар'ян Венема

Так. Під час написання коментаря було додано додатковий коментар та оновлення допису. І все-таки BinarySignWriting цікавий.
TRiG

2

Unicode визначає карту між числами та символами. Однак, коли ви надсилаєте номер одержувачу, вам все одно потрібно визначити, як представити це число. Ось для чого призначений UTF. Він визначає, як представити число в потоці байтів.


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 набагато простіше, ніж мати справу зі старою системою з сотень різних кодувань символів для різних мов та різних ОС.


1

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

Алгоритм блискавки насправді має кілька різних алгоритмів з різними характеристиками на вибір: збережений (без стиснення), скорочений, зменшений (методи 1-4), вкладений, токенізуючий, спущений, дефляційний64, BZIP2, LZMA (EFS), WavPack, PPMd, там, де теоретично можна було б спробувати їх усі та вибрати найкращий результат, але, як правило, просто перейдіть із «Дефляцією».

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


ørn: Різниця в zip-файлі полягає в тому, що є заголовок, який повідомляє вам про те, що відбувається компресія. З текстовими файлами нам ще потрібно здогадатися, чи не так?
Меттью Шарлі

Існує спеціальна послідовність, яка точно говорить про це. Через зворотну сумісність з ASCII вона не є обов'язковою.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.