- UTF-8 кодира Unicode точки в 1–4 байта, съвместим с ASCII и валиден за всеки език.
- Самосинхронизация и валидиране: Моделите 0/110/1110/11110 предотвратяват припокривания и улесняват откриването на грешки.
- Уеб и системи: мета кодиране, масивна поддръжка и лесно конвертиране в Windows/macOS/Linux.
Ако четете тази статия днес, без да виждате странни символи, това е благодарение на UTF-8 . Това кодиране позволява букви, ударения, технически символи и дори емоджита да се показват по един и същи начин във всеки съвременен браузър, операционна система или имейл клиент. Това е най-разпространеният стандарт в мрежата и основата на дигиталната комуникация, каквато я познаваме.
Когато едно устройство показва текст, то всъщност обработва числа . Тези числа са кодови точки, дефинирани от стандарта Unicode , и за да ги преобразуваме в байтове, които пътуват по мрежа или се запазват във файл, извършваме трансформация: UTF-8 . В следващите редове ще разберете какво представлява, как работи, защо е станал стандарт, неговите предимства и ограничения и как да избегнете често срещани грешки.
Какво е UTF-8?
UTF-8 (8-битов Unicode Transformation Format) е начин за трансформиране на Unicode кодови точки в байтови поредици . Ключовата му характеристика е, че използва променлива дължина : някои символи заемат 1 байт, докато други изискват 2, 3 или 4 байта. Това позволява компактни текстове с прости латински символи , но може да представлява и всеки символ от Unicode репертоара.
Той е напълно съвместим с ASCII : първите 128 символа (от U+0000 до U+007F) са кодирани с един байт, идентичен със 7-битовия ASCII. Това улесни прехода от по-стари системи и обяснява голяма част от успеха му в интернет, електронната поща и IETF протоколите.
UTF-8 се откроява със своята устойчивост : той включва битове за синхронизация, които позволяват надеждно идентифициране на началото на всеки символ. Това свойство за самосинхронизация улеснява откриването дали дадена последователност „изглежда“ като UTF-8 , което е много полезно в инструменти и парсери.
Unicode: Основата на всичко
Unicode е универсалният стандарт, който присвоява уникален номер на всеки символ , независимо от езика, платформата или приложението. Това число се нарича кодова точка и обикновено се записва в шестнадесетичен формат U+XXXX (или повече цифри, ако е необходимо).
Например Главната буква „А“ е U+0041В HTML можем да го наречем още A. Вашият компютър не „мисли“ за А като за буква, а като за числото 65., и след това кодирането (като UTF-8) решава как да представи това число в байтове.
Ако искате да видите как Unicode се превежда в символи на вашия компютър , в Windows можете да задържите клавиша Alt и да въведете десетичния цифров код на цифровата клавиатура: например Alt+65 връща „A“ (вижте пълния списък с Alt кодове ). Това е класически пряк път, който показва как кодовете са в основата на символите, които виждате.
Малко история: как се е родил UTF-8
UTF-8 е разработен от Кен Томпсън под ръководството на Роб Пайк на 2 септември 1992 г. Те го внедряват в операционната система Plan 9 на Bell Labs и го представят официално на USENIX (Сан Диего, януари 1993 г.) . По време на стандартизацията му, спонсорирана от X/Open Joint Internationalization Group (XOJIG) , той е известен с имена като FSS/UTF и UTF-2, преди да бъде консолидиран като UTF-8.
Дизайнът реши практически проблеми , които измъчваха предишни опити за универсално кодиране: ASCII съвместимост, самосинхронизация, липса на припокриващи се байтове и лекота на откриване на грешки. Този баланс го направи де факто стандарт за мрежата.
Как работи UTF-8 „под капака“
UTF-8 групира символите според байтовете, необходими за кодирането им . Броят на байтовете зависи изключително от кодовата точка на Unicode и следва битови модели, които показват дължината на последователността.
- 1 байт (U+0000 до U+007F)ASCII символи. Формат:
0xxxxxxxНай-значимият бит е 0, който гарантира директна съвместимост с ASCII. - 2 байта (U+0080 до U+07FF): Формат
110yyyyy 10xxxxxx. Използва се за повечето европейски азбуки с диакритични знаци и други, като гръцка, кирилица, иврит или арабска.. - 3 байта (U+0800 до U+FFFF): Формат
1110zzzz 10yyyyyy 10xxxxxx. Включва многоезичен основен план (BMP), с CJK (китайски, японски, корейски), технически символи и най-често използвани знаци. - 4 байта (U+10000 до U+10FFFF): Формат
11110uuu 10uuzzzz 10yyyyyy 10xxxxxx. Представлява допълнителните равнини: усъвършенствани математически символи, исторически писания, по-рядко срещани идеографски символи и др.
Ключът към самосинхронизацията се крие в заглавните битове : 0 за ASCII; 110 за два байта; 1110 за три; 11110 за четири. Продължаващите байтове винаги започват с 10. Благодарение на това, продължаващият байт никога не може да се появи като начален байт , а валидна последователност никога не може да бъде подниз на по-дълъг (принцип на неприпокриване).
Еквивалентност с UTF-16 и сурогатни двойки
UTF-16 представлява BMP кодови точки с единица от 16 бита. и точки над U+FFFF с заместващи двойки в диапазона D800–DFFF, Вместо това, UTF-8 винаги кодира реални кодови точки, а не UTF-16 единици, което избягва объркване със заместители.
В исторически план някои чернови са позволявали 5 или 6 байта в UTF-8, за да покрият по-широк диапазон, но Unicode и RFC 3629 ограничават UTF-8 до максимум 4 байта . ISO/IEC разглеждаше по-широки опции, но те не са част от настоящия стандарт.
Практически пример: ñ
Символът „ñ“ има кодова точка U+00F1, което попада в двубайтовия диапазон. Следвайки шаблона, то се кодира като 110xxxxx 10xxxxxx. UTF-8 представянето му е 0xC3 0xB1Декодирането е обратен процес: четене на полезните битове и възстановяване на оригиналната кодова точка.
Предимства и ограничения на UTF-8
Основни предимства :
- Поддръжка на ASCIIASCII текстовете са валидни в UTF-8 без промени.
- Универсален: може да представлява всеки Unicode символ, включително технически символи и емоджита.
- Ефективност в латински текстове: при използване на 1 байт за ASCII, спестява място в сравнение с UTF-16 на много западни езици.
- Самосинхронизация и откриване: битовите модели позволяват откриване на началото на символите и валидирайте последователностите с лекота.
Ограничения и компромиси :
- Текстовете в CJK заемат повече място от текстовете в UTF-16, където много от тези символи се побират в 2 фиксирани байта.
- Разходи за изчисление: тъй като е с променлива дължина, някои операции (напр. „отиване до символ n“) изискват преминаване от самото начало, а някои задачи може да са по-бързи в UTF-16/UTF-32.
BOM (маркер за байтов ред) в UTF-8
UTF-8 не се нуждае от BOM защото редът на байтовете не променя значението на стойностите (най-малката единица е байтът). Въпреки това, Има опционална BOM (специализация), символът U+FEFF е кодиран като EF BB BF в началото на файл или поток, което може да се използва, за да се посочи „това е Unicode/UTF-8“.
Най-добри практики : Ако се появи в началото, някои системи го приемат, а други го третират буквално. При конкатенации е препоръчително да се премахнат междинни BOM-и . Включването му не е задължително и полезността му в UTF-8 е ограничена в сравнение с UTF-16/UTF-32, където той маркира endianness.
Типични грешки при кодиране и как да се справите с тях
Надеждният UTF-8 декодер трябва или да отхвърли деформираните последователности , или да ги замени с U+FFFD (ЗАМЕСТВАЩ СИМВОЛ), или да сигнализира за грешка. Най-често срещаните грешки са:
- Съкратени последователности: многобайтов водещ байт без достатъчно продължение.
- Свободни байтове за продължаване: появяват се
10xxxxxxбез валиден водещ байт. - Превишаващи дължиникодиране с повече байтове от необходимото; например, опит за кодиране на ASCII с 2 байта (
0xC0y0xC1са невалидни). - Забранени дължинизапочва да предлага 5 или 6 байта (
0xF8-0xFDне са валидни в стандарта UTF-8). - Стойности извън Unicode диапазона: не се поддържа над U+10FFFFопределени стойности (
0xF5-0xF7като начала) са невалидни. - UTF-16 сурогатни двойки:
D800–DFFFне са валидни кодови точки в Unicode; те не трябва да изглеждат кодирани в UTF-8.
Когато видите символа „�“ на екрана , най-вероятно това се дължи на несъответствие в кодирането или на файл, запазен в различна кодова страница. Решението е да се наложи UTF-8 кодиране от край до край (файл, сървър, база данни, HTTP заглавки).
UTF-8 в мрежата и в имейла
HTML страницата трябва да декларира само едно кодиране . Препоръчителното кодиране, за съвместимост и обхват, е UTF-8. Включете следния мета таг в заглавката възможно най-скоро:
<meta charset="UTF-8">
Поставете го в началото на тага `<head>`, така че браузърът да го прочете преди да обработи документа. Това предотвратява несъответствия и „счупени“ символи. UTF-8 се използва от огромното мнозинство от съвременните уебсайтове.
В електронната поща UTF-8 е широко поддържан и препоръчван от организации като Internet Mail Consortium. Конфигурирането на имейл клиенти да използват UTF-8 намалява проблемите при обмен на съобщения с хора, които говорят други езици.
UTF-8, UTF-16 и UTF-32: Каква е разликата?
UTF-8 : Кодиране с променлива дължина в 8-битови единици; идеално за уеб , много ефективно с ASCII и западни езици. Отлична съвместимост и откриване на грешки.
UTF-16 : променлива дължина в 16-битови единици; използва сурогатни двойки за U+10000 и нагоре. Често е предимство, когато преобладават символи, различни от ASCII , и се използва в много API и платформи (например, Windows работи нативно в UTF-16 ).
UTF-32 : фиксирана дължина от 32 бита на символ; много лесна за индексиране , но заемаща голямо пространство. Запазена е за случаи, когато размерът е второстепенен спрямо простотата на обработка.
Несъвместими варианти: CESU-8 и „Modified UTF-8“
CESU-8 кодира директно UTF-16 единици (включително сурогатни двойки), вместо да кодира кодови точки, като по този начин се различава от стандартния UTF-8 за символи над U+FFFF. Някои исторически платформи го използваха: Oracle 8 го предлагаше под псевдонима UTF-8, а започвайки с Oracle 9, добавяше стандартния UTF-8 под различен псевдоним. Java и Tcl са използвали CESU-8 в определени контексти.
Модифицираният UTF-8 (например в Java среди) представя символа NUL (U+0000) като 0xC0 0x80 вместо 0x00. Той избягва нулевия байт в C низовете , но не е съвместим със стандарта UTF-8. Много реализации на тази „модифицирана“ версия също така отговарят на CESU-8.
UTF-8 на Windows и API: Кодови страници и преобразуване
Windows работи вътрешно в UTF-16 (WCHAR) кодиране, но от Windows 10 версия 1903 можете принудително използване на UTF-8 като кодова страница на процеса чрез манифеста на приложението (свойство activeCodePage). Това улеснява работата на остарелия код, който използва API с „-A“, върху UTF-8.
API -A срещу -W: the -A зависи от кодовата страница на ANSI конфигуриран (може да бъде CP_UTF8), докато -W те използват UTF-16За да работят оперативно, Многобайтов към широк символ y ШирокоСъставянеКъмМногоБайтове позволяват ви да конвертирате между UTF-8 и UTF-16; САЩ CP_UTF8 и, ако е приложимо, MB_ERR_INVALID_CHARS за откриване на грешки при въвеждане.
UTF-8 е съвместим със съвременни браузъри (Chrome, Firefox, Safari, Edge, Opera и по-нови версии на Internet Explorer) и повечето операционни системи (Windows, Linux, macOS, Android, iOS). Освен ако нямате много стар софтуер, не би трябвало да имате проблеми.
Как да конвертирате файлове в UTF-8
В Windows (Notepad) : отворете файла, отидете на "File > Save As…" и в "Encoding" изберете UTF-8 . Запазете с ново име, ако искате да запазите оригинала.
В macOS (TextEdit) : В „TextEdit > Preferences > Open & Save“ изберете Unicode (UTF-8) при запазване. След това експортирайте файла с активирана тази опция.
На Linux: с терминала можете да използвате iconv, Например: iconv -f <codificación_origen> -t UTF-8 <entrada> -o <salida>. Проверете по-късно че приложението, което го използва, също очаква UTF-8.
Как можете да разберете дали даден файл е в UTF-8? Много съвременни редактори показват това в лентата на състоянието. Ако видите странни символи като „�“, повредени ударения или неправилно показани „ñ/ç“, проверете кодирането на файла и настройките на редактора/сървъра/базата данни.
Добри практики за избягване на изненади
Декларирайте UTF-8 възможно най-рано в HTML и HTTP заглавките. Подравнете кодирането в целия стек (изходни файлове, шаблони, база данни и връзка). Избягвайте смесване на кодировки на една и съща страница или поток и използвайте инструменти, които валидират/нормализират входните данни.
За интеграции и API, винаги посочвайте кодирането в заглавките (Content-Type: application/json; charset=UTF-8, например). Тест с многоезични данни (акценти, CJK, емоджита) за откриване на слаби места преди продукцията.
UTF-8 преобладава, защото балансира съвместимост, ефективност и обхват . Това е най-практичният начин да се гарантира, че текстът се предава непокътнат в различни култури, системи и приложения, независимо дали включва акценти, технически символи или нелатински писмености.