Юнікод
Юніко́д, (англ. Unicode), УНІфіковане КОДування — промисловий стандарт, розроблений, щоб забезпечити цифрове представлення символів усіх писемностей світу та спеціальних символів. Удосконалений сумісно з стандартом Універсальний Набір Символів (Universal Character Set — UCS) і опублікований у формі книги Стандарт Юнікод, Юнікод складається з асортименту символів, методології кодування та комплекту (набору) стандартів кодування символів, комплекту кодових таблиць для посилань на зображення символів, списку властивостей символів таких, наприклад, як верхній і нижній регістр (розкладка), комплект довідкових даних комп'ютерних файлів, правил нормалізації, декомпозиції, зіставлення і зображення (рендерингу).
Огляд
Стандарт запропонувала в 1991 році організація Консорціум Юнікоду (англ. Unicode Consortium), яка об'єднує найбільші ІТ-компанії (корпорації). Консорціум Юнікоду — неприбуткова (некомерційна) організація, яка координує розвиток Юнікоду, має амбітну мету замінити в кінцевому підсумку існуючі системи кодування символів Юнікодом і його системою стандартів Формат Перетворень Юнікоду (UTF, Unicode Transformation Format), тому що багато існуючих систем кодування є обмеженими в розмірі й можливостях і несумісними з багатомовними середовищами. Успіхи Юнікоду в уніфікації наборів символів призвели до його розповсюдження і домінуючого використання в інтернаціоналізації і локалізації програмного забезпечення комп'ютерів. Стандарт був використаний у багатьох новітніх технологіях, наприклад, у XML, мові програмування JavaScript і сучасних операційних системах.
Юнікод знімає старе обмеження на кодування символів лише одним байтом. Натомість використовується 17 просторів, кожен з яких визначає 65,536 кодів і дає можливість описати максимум 1 114 112 (17 * 216) різних символів. Basic Multilingual Plane (BMP) — Основна Багатомовна Площина містить майже всі символи, які ви будете коли-небудь використовувати.
Юнікод має декілька реалізацій, але найпоширенішими є дві: UTF (Unicode Transformation Format) — Формат Перетворення Юнікоду та UCS (Universal Character Set) — Універсальна Таблиця Символів. Число після UTF визначає кількість бітів, що виділені під один юніт, а число після UCS визначає кількість байтів. Універсальний набір символів задає однозначну відповідність символів кодам — елементам кодового простору, тобто невід'ємним цілим числам. UTF-8 став найпоширенішим для інтернаціональних кодувань.
UTF-8 є системою кодування зі змінною довжиною кодування символів. Це означає, що для кодування символів він використовує від 1 до 4 байт на символ. Так, перший байт UTF-8 можна використовувати для кодування ASCII, що дає повну сумісність з кодами ASCII. Перекодування кодів ASCII у кодах UTF-8 для латинських символів не збільшить розмір даних, бо для цього використовується тільки один байт на символ. Для символів інших мов, де, наприклад, для кодування треба використовувати два байти на символ, це кодування збільшує розмір даних на, приблизно, 50 % або більше.
UTF-8 дозволяє працювати в стандартизованому міжнародно прийнятому багатомовному середовищі, з порівняно незначним збільшенням обсягу даних. UTF-8 являє собою ідеальний спосіб передачі символів через Інтернет, електронну пошту, чат тощо.
Коди в стандарті Unicode поділені на декілька областей. Область з кодами від U+0000 до U+007F (про запис виду «U+xxxx» дивись нижче в розділі «Кодовий простір») містить символи набору ASCII. Далі розміщені області знаків різних писемностей, знаки пунктуації і технічні символи. Частина кодів зарезервована для використання в майбутньому. Для символів кирилиці виділені коди від U+0400 до U+052F (див. Кирилиця в Юнікоді).
Розділи стандарту Юнікод
Стандарт Unicode складається з двох основних розділів: універсальний набір символів і сімейство кодувань. Універсальний набір символів задає однозначну відповідність символів кодам — елементам кодового простору, що є невід'ємними цілими числами. Сімейство кодувань визначає машинне подання послідовності кодів універсального набору символів.
- Стандарти наборів символів
UCS-4 (англ. Universal Character Set) — 1 символ = 4 байти, всього можна закодувати 232 = 4 294 967 296 символів. Проте максимальна кількість Юнікод-символів на сьогодні — 220 + 216 = 1 114 112.
UCS-2 (англ. Universal Character Set) — 1 символ = 2 байти, всього можна закодувати 216 = 65 536 символів.
- Стандарти кодувань
UTF-32 (англ. Unicode Transformation Format — формат перетворення Юнікода) — один із способів кодування символів із Unicode у вигляді 32-бітових послідовностей. 1 символ = 32 біти.
UTF-16 — один із способів кодування символів із Unicode у вигляді 16-бітних послідовностей. Символи з кодами менше 0x10000 (216) представляються як є (одна 16-бітова послідовність), а символи з кодами 0x10000–0x10FFFE — у вигляді двох 16-бітових послідовностей (так звана «сурогатна» пара), перша з яких лежить в діапазоні 0xD800–0xDBFF, а друга — 0xDC00–0xDFFF. Легко бачити, що існує 210 * 210 = 220 таких комбінацій. А загальна кількість можливих символів 220 + 216 = 1 114 112. Слід зазначити, що за стандартом ніякі символи не можуть мати кодів власне з діапазону 0xD800-0xDFFF, так що розшифровка кодування завжди однозначна. Втім, в переважній більшості випадків текст в UTF-16 є просто послідовністю символів з UCS-2, оскільки символи Unicode після коду 0x10000 використовуються вкрай рідко.
UTF-16LE та UTF-16BE — у потоці даних UTF-16 старший байт може записуватися або перед молодшим (UTF-16 Big Endian або UTF-16BE), або після молодшого (UTF-16 Little Endian або UTF-16LE). Іноді кодування Юнікода Big Endian (UTF-16BE) називають Юнікодом із зворотним порядком байтів. Аналогічно існує два варіанти 32-бітового кодування: UTF-32LE та UTF-32BE.
UTF-8 — поширене сьогодні кодування, що реалізовує представлення Юнікода, сумісне з 8-бітовим кодуванням тексту. Текст, що складається тільки з символів з номером менше 128, при записі в UTF-8 перетворюється на звичайний текст ASCII. І навпаки, в тексті UTF-8 будь-який байт із значенням менше 128 зображає символ ASCII з тим же кодом. Решта символів Юнікода зображається послідовностями завдовжки від 2 до 6 байтів (реально тільки до 4 байт, оскільки використання кодів більше 2²¹ не планується), в яких перший байт завжди має вид 11xxxxxx, а інші — 10xxxxxx.
Простіше кажучи, у форматі UTF-8 символи латинського алфавіту, розділові знаки і керуючі символи ASCII, записуються ASCII-кодами, а решта всіх символів кодується за допомогою октетів (послідовності завдовжки 8 бітів) зі старшим бітом 1. У результаті, навіть якщо програма не розпізнає Юнікод, то латинські букви, арабські цифри і розділові знаки зображатимуться правильно.
Символи UTF-8 отримують з Unicode таким чином:
Unicode UTF-8 0x00000000 — 0x0000007F: 0xxxxxxx
0x00000080 — 0x000007FF: 110xxxxx 10xxxxxx
0x00000800 — 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
0x00010000 — 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Також теоретично можливі, але не включені в стандарти:
Unicode UTF-8 0x00200000 — 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0x04000000 — 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
Маркер порядку байтів
Для визначення формату представлення Юнікода в текстовому файлі використовується прийом, за яким на початку тексту записується символ U+FEFF (нерозривний пропуск з нульовою шириною), також іменований міткою порядку байтів (англ. Byte Order Mark, BOM). Цей спосіб дозволяє розрізняти UTF-16LE і UTF-16BE, оскільки символу U+FFFE не існує. Також він іноді застосовується для позначення формату UTF-8, хоча до цього формату і непридатне поняття порядку байтів. Файли, які дотримуються цього правила, починаються з таких байтів:
- UTF-8: EF BB BF
- UTF-16BE: FE FF
- UTF-16LE: FF FE
- UTF-32BE: 00 00 FE FF
- UTF-32LE: FF FE 00 00
Кодовий простір
Хоча форми запису UTF-8 і UTF-32 (8 і 32 - десяткові числа, які вказують кількість двійкових розрядів) дозволяють кодувати до 231 (2 147 483 648) кодових позицій, було прийнято рішення використовувати лише 220+216 (1 114 112) для сумісності з UTF-16. Втім, навіть і цього більш ніж достатньо — сьогодні (у версії Unicode 5.0) використовується трохи більше 99 000 кодових позицій.
Кодування та типи текстових даних мови С/С++
У мові С/С++ історично склалася така ситуація. Для роботи зі «звичайними» текстовими даними існує тип char. Для роботи з, так званим, «широким» текстом існує тип wchar_t. Особливості використання цих типів даних залежать від системи. А власне особливостями є кодування тексту в типах даних та розмір одного символу. Для порівняння візьмемо дві системи:
Linux
1. char («звичайний» текст)
- Кодування — UTF-8
- Розмір 1 символу — 1, 2, 3 або 4 байти
- sizeof(char) = 1
2. wchar_t («широкий» текст)
- Кодування — UTF-32
- Розмір 1 символу — 4 байти
- sizeof(wchar_t) = 4
Windows
1. char («звичайний» текст)
- Кодування — кодові сторінки
- Розмір 1 символу — 1 байт
- sizeof(char) = 1
2. wchar_t («широкий» текст)
- Кодування — UTF-16
- Розмір 1 символу — 2 або 4 байти
- sizeof(wchar_t) = 2
Висновки
Характерна особливість набору символів (UCS) — символи завжди фіксованої довжини:
- UCS-2 — 1 символ = 2 байти (лише одна площина з 17-ти)
- UCS-4 — 1 символ = 4 байти (65 тис. площин не використані)
Характерна особливість кодування (UTF) — символи НЕ завжди фіксованої довжини:
- UTF-32 — єдине кодування з фіксованою довжиною символів, 1 символ = 32 біти = 4 байти, тому можна сказати, що код символу в UCS-4 дорівнює коду символу в UTF-32.
- UTF-16 — коди символів < 216 однозначно відповідають кодам символів з набору UCS-2. Коди решти символів (символи з кодом >= 216) є однозначними тільки для UTF-16.
- UTF-8 — коди символів < 128 однозначно відповідають кодам символів верхньої частини ASCII таблиці. Коди решти символів (символи з кодом >= 128) є однозначними тільки для UTF-8.
Твердження «1 байт = 1 символ» є застарілим і в переважній більшості практичних випадків є хибним. Довжина символу НЕ є фіксованою (виняток складає кодування UTF-32 та ASCII таблиця). Юнікод у програмах — добра платформа для підтримки багатомовності.