Якщо UTF-8 має 8 біт, чи не означає це, що може бути максимум 256 різних символів?
Перші 128 кодових точок такі ж, як і в ASCII. Але там сказано, що UTF-8 може підтримувати до мільйона символів?
Як це працює?
Якщо UTF-8 має 8 біт, чи не означає це, що може бути максимум 256 різних символів?
Перші 128 кодових точок такі ж, як і в ASCII. Але там сказано, що UTF-8 може підтримувати до мільйона символів?
Як це працює?
Відповіді:
UTF-8 не використовує постійно один байт, це 1-4 байти.
Перші 128 символів (US-ASCII) потребують одного байта.
Наступним 1920 символам для кодування потрібно два байти. Це охоплює решту майже всіх латинських алфавітів, а також грецький, кириличний, коптський, вірменський, іврит, арабський, сирійський та танський алфавіти, а також поєднання діакритичних знаків.
Три символи потрібні для символів в іншій Базовій багатомовній площині, яка містить практично всі загальновживані символи [12], включаючи більшість китайських, японських та корейських символів [CJK].
Чотири байти потрібні для символів в інших площинах Unicode, які включають менш поширені символи CJK, різні історичні сценарії, математичні символи та смайли (піктографічні символи).
джерело: Вікіпедія
UTF-8 використовує 1-4 байта на символ: один байт для символів ascii (перші 128 значень Unicode такі самі, як ascii). Але для цього потрібно лише 7 біт. Якщо встановлено найвищий біт ("знак"), це вказує на початок багатобайтової послідовності; кількість послідовних встановлених старших бітів вказує кількість байтів, потім 0, а решта бітів вносять значення. Для інших байтів два найвищі біти становитимуть 1 і 0, а решта 6 бітів - для значення.
Отже, послідовність із чотирьох байт починається з 11110 ... (і ... = три біти для значення), потім три байти з 6 бітами для кожного, отримуючи 21-бітове значення. 2 ^ 21 перевищує кількість символів Unicode, тому весь Unicode може бути виражений в UTF8.
Відповідно до цієї таблиці * UTF-8 повинен підтримувати:
2 31 = 147 483 688 символів
Однак RFC 3629 обмежив можливі значення, тому зараз ми обмежуємося 4 байтами , що дає нам
2 21 = 2097152 символів
Зверніть увагу, що велика частина цих символів "зарезервована" для користувальницького використання, що насправді дуже зручно для шрифтів значків.
* У використаній Вікіпедії показано таблицю з 6 байтами - з тих пір вони оновили статтю.
11.07.2017: Виправлено для подвійного підрахунку тієї самої кодової точки, кодованої кількома байтами
0xxxxxxx
дає 7 корисних бітів, 110xxxxx 10xxxxxx
дає ще 11 - немає перекриття. Перший байт починається з 0
першого випадку, а 1
у другому випадку.
00000001
зберігається, а що 11000000 100000001
зберігається?
Юнікод вирішує кодові точки до символів. UTF-8 - це механізм зберігання для Unicode. Unicode має специфікацію. UTF-8 має специфікацію. Вони обидва мають різні межі. UTF-8 має інший висхідний сигнал.
Unicode позначається "площинами". Кожна площина несе 2 16 кодових точок. У Unicode є 17 літаків. Для загальної кількості 17 * 2^16
кодових балів. Перша площина, площина 0 або BMP , є особливою в вазі , що він несе.
Замість того, щоб пояснювати всі нюанси, дозвольте мені просто процитувати вищевказану статтю про літаки.
17 літаків можуть вмістити 1114112 кодових точок. З них 2048 - це сурогати, 66 - не символи, 137 468 - зарезервовані для приватного користування, 974 530 - для державного призначення.
А тепер повернімось до статті, зв’язаної вище,
Схема кодування, яка використовується UTF-8, була розроблена з набагато більшим обмеженням у 2 31 кодовий пункт (32 768 площин) і може кодувати 2 21 кодовий пункт (32 площини), навіть якщо обмежений 4 байтами. [3] Оскільки Unicode обмежує кодові точки до 17 площин, які можуть кодуватися UTF-16, кодові точки вище 0x10FFFF є недійсними в UTF-8 та UTF-32.
Отже, ви можете бачити, що ви можете помістити в UTF-8 речі, які не є дійсним Unicode. Чому? Оскільки UTF-8 вміщує кодові точки, які Unicode навіть не підтримує.
UTF-8, навіть з обмеженням у чотири байти, підтримує 22 кодових точки, що набагато більше17 * 2^16
2164864 "символи" можуть бути потенційно закодовані UTF-8.
Це число 2 ^ 7 + 2 ^ 11 + 2 ^ 16 + 2 ^ 21, що походить від способу роботи кодування:
1-байтові символи мають 7 бітів для кодування
0xxxxxxx
(0x00-0x7F)
Двобайтові символи мають 11 біт для кодування
110xxxxx 10xxxxxx
(0xC0-0xDF для першого байта; 0x80-0xBF для другого)
3-байтові символи мають 16 бітів для кодування
1110xxxx 10xxxxxx 10xxxxxx
(0xE0-0xEF для першого байта; 0x80-0xBF для продовжуючих байтів)
4-байтові символи мають 21 біт для кодування
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
(0xF0-0xF7 для першого байта; 0x80-0xBF для продовження байтів)
Як бачите, це значно більше, ніж поточний Unicode (1112 064 символів).
ОНОВЛЕННЯ
Мій початковий розрахунок помилковий, оскільки він не враховує додаткові правила. Докладніше див. У коментарях до цієї відповіді.
UTF-8 - це кодування змінної довжини з мінімум 8 бітами на символ.
Символи з вищими кодовими точками займуть до 32 біт.
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
, тому для кодування фактичного символу можна використовувати лише 21 біт.
Цитата з Вікіпедії: "UTF-8 кодує кожну з 1112 064 точок коду в наборі символів Unicode, використовуючи від одного до чотирьох 8-бітових байтів (що називаються" октетами "у стандарті Unicode)."
Деякі посилання:
Ознайомтеся зі стандартом Unicode та пов’язаною інформацією, такою як запитання щодо часто заданих питань, UTF-8 UTF-16, UTF-32 та специфікація . Це не настільки плавне плавання, але це достовірна інформація, і багато з того, що ви могли прочитати про UTF-8 в інших місцях, є сумнівним.
"8" у "UTF-8" відноситься до довжини кодових одиниць у бітах. Одиниці коду - це сутності, які використовуються для кодування символів, не обов’язково як просте відображення один на один. UTF-8 використовує змінну кількість одиниць коду для кодування символу.
Колекція символів, яку можна закодувати в UTF-8, точно така ж, як і для UTF-16 або UTF-32, а саме всіх символів Unicode. Усі вони кодують весь простір кодування Unicode, який включає навіть не символи та непризначені кодові точки.
Хоча я погоджуюсь з mpen щодо поточних максимальних кодів UTF-8 (2164864) (перераховані нижче, я не міг прокоментувати його), він відключається на 2 рівні, якщо ви скасуєте 2 основні обмеження UTF-8: лише 4 байти limit і коди 254 і 255 не можна використовувати (він лише видалив обмеження в 4 байти).
Початковий код 254 слідує базовій схемі стартових бітів (багатобітовий прапор встановлений на 1, рахунок 6 1 і термінал 0, без запасних бітів), що дає вам 6 додаткових байтів для роботи (6 груп 10xxxxxx, додаткові 2 ^ 36 кодів).
Початковий код 255 точно не відповідає базовій установці, не використовується термінал 0, але використовуються всі біти, що дає вам 7 додаткових байтів (багатобітовий прапор встановлений в 1, рахунок 7 1, а термінал 0 не використовується, оскільки використовуються всі біти ; 7 груп 10xxxxxx, додаткові 2 ^ 42 коди).
Додаючи їх у, ви отримаєте остаточний максимальний презентабельний набір символів - 4 468 982 745 216. Це більше, ніж усі символи, які зараз використовуються, старі або мертві мови та будь-які втрачені мови. Ангельський чи Небесний сценарій хтось?
Також існують однобайтові коди, які не враховуються / ігноруються в стандарті UTF-8 на додаток до 254 та 255: 128-191 та декількох інших. Деякі з них використовуються клавіатурою локально, приклад коду 128, як правило, є зворотним простором видалення. Інші стартові коди (та пов'язані з ними діапазони) недійсні з однієї або кількох причин ( https://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences ).
Юнікод міцно одружений на UTF-8. Юнікод спеціально підтримує 2 ^ 21 кодових точок (2 097 152 символів), що є точно такою ж кількістю кодових точок, що підтримується UTF-8. Обидві системи резервують однаковий "мертвий" простір та зони обмеженого доступу для кодових точок тощо ... станом на червень 2018 року остання версія Unicode 11.0 містить репертуар із 137 439 символів
Зі стандарту Unicode. Поширені запитання про Unicode
Стандарт Unicode кодує символи в діапазоні U + 0000..U + 10FFFF, що становить 21-бітний простір коду.
Зі сторінки UTF-8 у Вікіпедії. UTF-8 Опис
Оскільки обмеження простору коду Unicode до 21-бітових значень у 2003 році, UTF-8 визначено для кодування точок коду в одному-чотирьох байтах, ...