Навіщо нам потрібен Unicode?
У (не надто) ранні дні все, що існувало, було ASCII. Це було нормально, оскільки все, що коли-небудь знадобилося, - це кілька контрольних символів, пунктуації, цифри та букви, як у цьому реченні. На жаль, сьогоднішній дивний світ глобальної взаємодії та соціальних медіа не передбачався, і не надто незвично в цьому ж документі бачити англійську, українську, іспанську, ελληνικά та ((сподіваюся, я не зламав жодного старого браузери).
Але заради аргументу, скажімо, Джо Середній - розробник програмного забезпечення. Він наполягає на тому, що йому буде потрібно лише коли-небудь англійська мова, і як такий хоче лише використовувати ASCII. Це може бути добре для Джо користувача , але це не добре для Джо розробника програмного забезпечення . Приблизно половина світу використовує не латинські символи, і використання ASCII є, мабуть, неуважним до цих людей, і, крім того, він закриває своє програмне забезпечення для великої та зростаючої економіки.
Тому необхідний набір символів, що включає всі мови. Так вийшов Unicode. Він присвоює кожному символу унікальне число, яке називається кодовою точкою . Однією з переваг Unicode перед іншими можливими наборами є те, що перші 256 кодових точок ідентичні ISO-8859-1 , а отже, і ASCII. Крім того, переважна більшість символів, що часто використовуються, представлені лише двома байтами в області, що називається базовою багатомовною площиною (BMP) . Тепер кодування символів потрібне для доступу до цього набору символів, і, як задається питанням, я сконцентруюся на UTF-8 та UTF-16.
Міркування щодо пам'яті
Отже, скільки байтів надають доступ до тих символів у цих кодуваннях?
- UTF-8:
- 1 байт: Стандарт ASCII
- 2 байти: арабська, іврит, більшість європейських сценаріїв (найбільш винятково грузинська )
- 3 байти: BMP
- 4 байти: Усі символи Unicode
- UTF-16:
- 2 байти: BMP
- 4 байти: Усі символи Unicode
Зараз варто згадати, що символи, які не входять до BMP, включають стародавні сценарії, математичні символи, музичні символи та рідші китайські / японські / корейські символи.
Якщо ви будете працювати в основному з символами ASCII, то UTF-8, безумовно, ефективніше пам'яті. Однак, якщо ви працюєте в основному з неєвропейськими сценаріями, використання UTF-8 може бути в 1,5 рази менш ефективною пам'яттю, ніж UTF-16. У роботі з великою кількістю тексту, наприклад, великими веб-сторінками або довгими текстовими документами, це може вплинути на ефективність роботи.
Основи кодування
Примітка. Якщо ви знаєте, як кодуються UTF-8 та UTF-16, перейдіть до наступного розділу для практичних застосувань.
- UTF-8: Для стандартних символів ASCII (0-127) коди UTF-8 однакові. Це робить UTF-8 ідеальним, якщо потрібна зворотна сумісність із існуючим текстом ASCII. Для інших символів потрібно десь 2-4 байти. Це робиться за допомогою резервування деяких бітів у кожному з цих байтів, щоб вказати, що він є частиною багатобайтового символу. Зокрема, перший біт кожного байту -
1
це уникати зіткнення з символами ASCII.
- UTF-16: Для дійсних символів BMP представлення UTF-16 є просто його кодовою точкою. Однак для символів, що не належать до BMP, UTF-16 вводить сурогатні пари . У цьому випадку поєднання двох двобайтових ділянок відображає характер, що не належить до BMP. Ці двобайтові ділянки походять з числового діапазону BMP, але вони гарантуються стандартом Unicode як недійсні як символи BMP. Крім того, оскільки UTF-16 має два байти в якості основної одиниці, це впливає на витривалість . Для компенсації на початку потоку даних може бути розміщений зарезервований байт порядку, який вказує на витривалість. Таким чином, якщо ви читаєте вхід UTF-16, і не вказана небезпека, ви повинні перевірити це.
Як видно, UTF-8 і UTF-16 ніде не сумісні між собою. Тому якщо ви робите I / O, переконайтеся, що ви знаєте, яке кодування ви використовуєте! Детальнішу інформацію про ці кодування див. У відповідях на поширені питання UTF .
Практичні міркування щодо програмування
Характеристика та рядкові типи даних: Як вони кодуються мовою програмування? Якщо вони є необробленими байтами, у хвилину, коли ви спробуєте вивести символи, що не належать до ASCII, у вас можуть виникнути проблеми. Крім того, навіть якщо тип символу заснований на UTF, це не означає, що рядки є належним UTF. Вони можуть дозволити незаконні послідовності байтів. Як правило, вам доведеться використовувати бібліотеку, яка підтримує UTF, наприклад ICU для C, C ++ та Java. У будь-якому випадку, якщо ви хочете ввести / вивести щось інше, ніж кодування за замовчуванням, вам доведеться спочатку перетворити це.
Рекомендовані / за замовчуванням / домінуючі кодування: Коли вибираєте, який UTF використовувати, зазвичай краще дотримуватися рекомендованих стандартів для середовища, в якому ви працюєте. Наприклад, UTF-8 є домінуючим в Інтернеті, а оскільки HTML5 - це було рекомендовано кодування . І навпаки, обидва середовища .NET і Java засновані на типі символів UTF-16. Заплутано (і неправильно) часто посилаються на "кодування Unicode", яке зазвичай посилається на домінуюче кодування UTF у заданому середовищі.
Бібліотечна підтримка: Бібліотеки, якими ви користуєтеся, підтримують якесь кодування. Який? Чи підтримують вони кутові справи? Оскільки необхідність є основою винаходу, бібліотеки UTF-8, як правило, належним чином підтримують 4-байтові символи, оскільки 1, 2 і навіть 3-байтні символи можуть траплятися часто. Однак, не всі бібліотеки UTF-16 підтримують сурогатні пари належним чином, оскільки вони трапляються дуже рідко.
Підрахунок символів: У Unicode є об'єднання символів. Наприклад, кодова точка U + 006E (n) та U + 0303 (об'єднує тильда) утворює ñ, але кодова точка U + 00F1 утворює ñ. Вони повинні виглядати однаково, але простий алгоритм підрахунку поверне 2 для першого прикладу, 1 для другого. Це не обов'язково неправильно, але це може бути і не бажаним результатом.
Порівняння рівності: A, А та Α виглядають однаково, але вони відповідно латині, кирилиці та грецькій мові. У вас також є випадки типу C і and, один - літера, а другий - римська цифра. Крім того, ми маємо враховувати і комбінуючі символи. Для отримання додаткової інформації див. Копії символів у Unicode .
Сурогатні пари: Вони з'являються досить часто на SO, тому я надам лише кілька прикладних посилань:
Інші ?: