Пятница, 29.11.2024, 00:29
Приветствую Вас, Гость
Главная » 2015 » Сентябрь » 10 » UTF-8
22:31
UTF-8
UTF-8 (від англ. Unicode Transformation Format, 8-bit — «формат перетворення Юнікод, 8-бітний») — одна із загальноприйнятих і стандартизованих кодувань тексту, яка дозволяє зберігати символи Юнікоду.

Стандарт UTF-8 офіційно закріплений у документах RFC 3629 [7] та ISO/IEC 10646 Annex D. Кодування знайшла широке застосування в UNIX-подібних операційних системах та на веб-просторі[1]. Сам же формат UTF-8 був винайдений 2 вересня 1992 року Кеном Томпсоном і Робом Пайком і реалізований у Plan 9.[2] В якості BOM використовує послідовність байт EF16, BB16, BF16 (що у неї самої є трехбайтовой реалізацією символу FEFF16).

Однією з переваг є сумісність з ASCII — будь-які їх 7-бітні символи відображаються як є, а решту видають користувачеві сміття (шум). Тому у разі, якщо латинські букви і прості знаки пунктуації (включаючи пробіл) займають істотний обсяг тексту, UTF-8 дає виграш за обсягом порівняно з UTF-16

Алгоритм закодирования в UTF-8 стандартизований в RFC-3629 [7] і складається з 3-х пунктів:

( Для номерів з U+0000 до U+007F кодування UTF-8 повністю відповідає 7-бітному US-ASCII c 0 в першому бите і займає один октет(байт). )

1.
Визначити кількість октетів(байт), необхідних для даного (кодованого) номери символу (c U+0100 по U+10FFFF) і перший стовпець у таблиці вище([7]). Дуже
важливо відзначити, що рядки таблиці є взаємовиключними, тобто: Є Лише Один Правильний спосіб кодування даного символу.

2.
 Підготувати старші біти першого октету (відповідають за кількість октетів), як у другому стовпці таблиці 110xxx -два октету, 1110xxx -три, 11110xx -чотири).

3.
Заповнити решту (від старших) біти (відмічені х) у знайдених в П. 1 октетах, номером символу (U+nnnnn), вираженому в двійковому вигляді.
Почати з молодших бітів номера символу, поставивши їх у молодші біти останнього октету коду. І так далі, поки всі біти номера символу не будуть перенесені у Вільні біти октетів.
Докладніше: дивись RFC-3629 [7]

1. Якщо розмір символу в кодуванні UTF-8 = 1 байт
Код має вигляд (0aaa aaaa), де «0» — нульовий біт, решта біти «a» — це код символу в кодуванні ASCII;

2. Якщо розмір символу в кодуванні UTF-8 > 1 байт (тобто від 2 до 6):
2.1 Перший байт
2.1.1 містить кількість байт символу, закодоване в одиничній системі числення;
2 — 11
3 — 111
4 — 1111
5 — 1111 1
6 — 1111 11
2.1.2 «0» — біт-термінатор, що означає завершення коду розміру
2.1.3 решта біти — значущі
2.2 далі йдуть значущі байти коду, які мають вигляд (10xx xxxx), де «10» — біти ознаки продовження, а x — значущі біти.


У загальному випадку варіанти представлення одного символу в кодуванні UTF-8 виглядають так:
(1 байт) 0aaa aaaa
(2 байти) 110x xxxx 10xx xxxx
(3 байти) 1110 xxxx 10xx xxxx 10xx xxxx
(4 байта) 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
(5 байт) 1111 10xx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx
(6 байт) 1111 110x 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx

Приклад

Код BOM для UTF-8 = EF BB BF(16) = 1110 1111 1011 1011 1011 1111(2) 1 байт 2 байт байт 3
(3 байти) 1110 xxxx 10xx xxxx 10xx xxxx
bin 1110 1111 1011 1011 1011 1111
hex EF BB BF

Кількість
байт UTF-8 Кількість
значущих біт
1 7
2 +4 11
3 +5 16
4 +5 21
5 +5 26
6 +5 31


У загальному випадку кількість значущих біт C, кодуються n байтами UTF-8, визначається за формулою:

C = 7 при n=1

C = n*5+1 при n>1

Значущі біти у формі запису UTF-32BE розташовуються поспіль, починаючи з заповнення молодшого байта. Завдання перетворення UTF-32BE в UTF-8 зводиться до вибору відповідної форми UTF-8 і копіювання значущих бітів UTF-32BE без додаткових перетворень.
Дуже часто потрібно перевіряти наявність старших бітів числа.
Наступний код на мові Сі виключає випадкові описки при наборі маски
#define UTF8_MASK( bits ) ( ~( int )0 << bits )

if ( !( value & UTF8_MASK( 7 ) ) ) // 7 - кількість значущих біт.
// Можна підставляти також: 11, 16, 21, 26, 31.
{
// Виконується, якщо у числа немає бітів, встановлених в "1", крім молодших 7
}
Попередній код буде замінений препроцесором на цей:
if ( !( value & 0xFFFFFF80 ) )
{

}

У таблиці нижче представлені в шістнадцятковій системі числення. На практиці для кожного значення вибирається єдине вірне уявлення за алгоритмом стандартизованому в RFC-3629 [] (з мінімальною довжиною байт, великі — не можна; та представлені для наочності і тестів кодувальників).Значення 1 байт 2 байта 3 байти 4 байти 5 6 байт байт
0000
(NUL) 00 C0 80 E0 80 80 F0 80 80 80 F8 80 80 80 80 FC 80 80 80 80 80
0073
(мала латинська «s») 73 B3 C1 E0 81 B3 F0 80 81 B3 F8 80 80 81 B3 FC 80 80 80 81 B3
041A
(велика кирилична «До») - D0 9A E0 90 9A F0 80 90 9A F8 80 80 90 9A FC 80 80 80 90 9A
0BF5
(«௵» — рік на тамільською) - - E0 AF B5 F0 80 AF B5 F8 80 80 AF B5 FC 80 80 80 AF B5
D7FF
(останній символ перед сурогатом UTF-16) - - ED 9F BF F0 8D 9F BF F8 80 8D 9F BF FC 80 80 8D 9F BF
D800
(перший символ сурогатів UTF-16) - - ED A0 80 F0 8D A0 80 F8 80 8D A0 80 FC 80 80 8D A0 80
DFFF
(останній символ сурогатів UTF-16) - - ED BF BF F0 8D BF BF F8 80 8D BF BF FC 80 80 8D BF BF
E000
(перший символ після сурогатів UTF-16) - - EE 80 80 F0 8E 80 80 F8 80 8E 80 80 FC 80 80 8E 80 80
26218
(«�» — китайський ієрогліф) - - - F0 A6 88 98 F8 80 A6 88 98 FC 80 80 A6 88 98
10FFFF
(максимальний код Unicode) - - - F4 8F BF BF F8 84 8F BF BF FC 80 84 8F BF BF
110000
(перший код після максимального Unicode) - - - F4 90 80 80 F8 84 90 80 80 FC 80 84 90 80 80
ABCDEF
(довільне 5-байтове) - - - - F8 AA BC B7 AF FC 80 AA BC B7 AF
7FFFFFFF
(максимальний код UCS-4) - - - -

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

Алгоритм UTF-8 технічно дозволяє записувати код будь-якої довжини. Але для ефективної і надійної роботи алгоритму необхідно обмеження довжини коду. Діючий стандарт Unicode 6.х передбачає використання коду до 21-го біта, тобто до чотирьох байт в UTF-8.

Відмінні значення байтів представлені в першу чергу для використання в алгоритмах автоматичного визначення кодування тексту. Первинною ознакою можна вважати BOM, яка підвищує ймовірність використання тієї чи іншої кодування (див. окрему статтю). Іншою ознакою є виявлення не валідних або сильно малоймовірних байт, або ж навпаки ймовірних. Тут же слід зазначити, що UTF-8 підтримує кодування 31-бітних кодів UCS-4. Якщо мова стосується символів Unicode, то п'яти - і шестибайтовые значення виявляються сильно малоймовірними. І є ще один примітний момент — в кодуванні UTF-8 можливе надлишкове кодування, що породжує багатозначність. Наприклад, ASCII-символ можна закодувати шістьма варіантами байтових послідовностей, але це не означає не валідність надлишкових байтових послідовностей. І тут можна впасти в оману коли перший байт містить тільки нульові біти значення — для послідовностей вище двох байт виключно це нормально.

Усі значення подані у шістнадцятковій системі числення. Під значенням «дуже малоймовірний» у колонці «статус» слід розглядати використання кодувальника, який не відкидає лідируючі нулі.Значення байта Статус Значення
00..7F без сумнівів ASCII-символи.
80..BF без сумнівів Будь не перший байт символу.
С0..C1 надлишкове кодування Перший байт двобайтового символу, який містить ASCII-код.
C2..DF без сумнівів Перший байт двобайтового символу.
E0 невеликі сумніви Перший байт трехбайтового символу, але ним же можуть починатися символи з надмірною кодуванням (послідовності E0 80 і E0 81).
E1..EF без сумнівів Перший байт трехбайтового символу.
F0 невеликі сумніви Перший байт четырехбайтового символу, але ним же можуть починатися символи з надмірною кодуванням (послідовності F0 80 A0 і нижче за останнім байту).
F1..F7 без сумнівів Перший байт четырехбайтового символу.
F8 невеликі сумніви Перший байт пятибайтового символу, але ним же можуть починатися символи з надмірною кодуванням (послідовності F0 80 і F0 87).
F9..FB без сумнівів Перший байт пятибайтового символу, не використовується для кодування Unicode.
FC невеликі сумніви Перший байт шестибайтового символу, але ним же можуть починатися символи з надмірною кодуванням (послідовності FС 80 і F0 83).
FD без сумнівів Перший байт шестибайтового символу, не використовується для кодування Unicode.
FE..FF неможливі при кодуванні аж до 31 біт першого байта символу встановлюється стільки старших бітів, скільки байтів відводиться під символ. Їх кінець позначається термінальним бітом 0, а решта біти відповідають старшим бітам значення. Байти 254 і 255 в двійковій системі: 111111102 і 111111112 відповідають довжинам 7 і 8, а довжина 31 біт може бути закодований шістьма байтами.

Нижче наведені приклади для швидкої орієнтації у випадках некоректного декодування тексту (так звані кракозябры[en]).

Так виглядає фраза «Людина зараз побачить лише те, що очікує побачити.» якщо вона сприйнята декодировщиком в кодуванні Windows-1251, а не UTF-8:



ЧеР"овек сейчас СѓРІРеРґРеС' Р"Решь З'являється Рѕ, З‡З'являється Рѕ РѕР¶РедаеС' СѓРІРеРґРµС'СЊ.

Фраза «Людина зараз побачить лише те, що очікує побачити.» при подвійному кодуванні UTF-8, UTF-8:



ЧРµРВ"РѕРІРµРС" СЃРµРв"-час РЎС"РІРЄ Р Т'к. Р З'являється С‚ Р В"Р З'являється РЎв'РЎРЉ то, что ожЪ Р Т'к. ает РЎС"РІРЄ Р Т'к. еть.

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

UTF-8 має властивість самосинхронізації при обробці 8-бітовими байтами. Альтернативною UTF-8 є кодування UTF-16, яка вже обробляється 16-бітними словами. Можливе виникнення сумніву що UTF-16 не є самосинхронизирующейся. На даний момент передача даних в комп'ютері в переважній більшості проводиться цільними октетами — 8 біт або нічого (див. IPv4, IPv6, SATA для сучасної апаратури і ATA з PATA для недавньої). У даних умовах UTF-8 має перевагу в характеристиці самосинхронізації перед UTF-16, якщо мова стосується апаратної передачі даних або для роботи з байтовим потоком (читання Unicode-даних з довільної позиції). Якщо ж робота здійснюється в оперативній пам'яті машини, то UTF-16 так само є самосинхронизирующейся (якщо апаратура здатна подавати цілісні 16-бітні слова).
Просмотров: 416 | Добавил: Admin | Теги: UTF-8 | Рейтинг: 0.0/0
Всего комментариев: 0
avatar