Введение
ASCII-совместимая кодировка Unicode переменной ширины, использующая от одного до четырех байт. UTF-8 — это стандарт кодирования символов переменной длины, используемый для электронной связи. Определенный стандартом Unicode, его название происходит от Unicode Transformation Format 8 bit. UTF-8 способен кодировать все 1 112 064 допустимых кодовых точек Unicode, используя от одного до четырех однобайтовых (8-битных) кодовых единиц. Кодовые точки с меньшими числовыми значениями, которые обычно встречаются чаще, кодируются меньшим количеством байтов. Он был разработан для обратной совместимости с ASCII: первые 128 символов Unicode, соответствующие символам ASCII один к одному, кодируются одним байтом с тем же двоичным значением, что и в ASCII, поэтому допустимый текст ASCII также является допустимым Unicode, закодированным в UTF-8. UTF-8 был разработан как превосходящая альтернатива UTF-1, предлагаемой кодировке переменной длины с частичной совместимостью с ASCII, которой не хватало некоторых функций, включая самосинхронизацию и полноценную обработку символов, таких как косая черта, совместимую с ASCII. Кен Томпсон и Роб Пайк создали первую реализацию для операционной системы Plan 9 в сентябре 1992 года. Это привело к его принятию X/Open в качестве спецификации для FSS UTF, которая была впервые официально представлена на USENIX в январе 1993 года и впоследствии принята Internet Engineering Task Force (IETF) в RFC 2277 (BCP 18) для будущих интернет-стандартов, заменяя однобайтовые кодировки символов, такие как Latin 1, в более старых RFC. UTF-8 приводит к уменьшению количества проблем с интернационализацией. Официальный орган по присвоению номеров в Интернете также указывает csUTF8 как единственный псевдоним, который используется редко. В Windows UTF-8 — это кодовая страница 65001 (т. е. CP UTF8 в исходном коде). В MySQL UTF-8 называется utf8mb4 (utf8mb3 и его псевдоним utf8 — это подмножество кодировки символов в базовой многоязычной плоскости). В HP PCL идентификатор символа для UTF-8 — 18N. В базе данных Oracle (начиная с версии 9.0) AL32UTF8 означает UTF-8. См. также CESU-8 — почти синоним UTF-8, который редко следует использовать. UTF-8 BOM и UTF-8 NOBOM иногда используются для текстовых файлов, содержащих или не содержащих метку порядка байтов (BOM) соответственно. Особенно в Японии кодировка UTF-8 без BOM иногда называется UTF-8N.
UTF 8 is a variable length character encoding standard used for electronic communication. Defined by the Unicode Standard, the name is derived from Unicode Transformation Format 8 bit. UTF 8 is capable of encoding all 1,112,064 valid Unicode code points using one to four one byte (8 bit) code units. Code points with lower numerical values, which tend to occur more frequently, are encoded using fewer bytes. It was designed for backward compatibility with ASCII: the first 128 characters of Unicode, which correspond one to one with ASCII, are encoded using a single byte with the same binary value as ASCII, so that valid ASCII text is valid UTF 8 encoded Unicode as well. UTF 8 was designed as a superior alternative to UTF 1, a proposed variable length encoding with partial ASCII compatibility which lacked some features including self synchronization and fully ASCII compatible handling of characters such as slashes. Ken Thompson and Rob Pike produced the first implementation for the Plan 9 operating system in September 1992. This led to its adoption by X/Open as its specification for FSS UTF, which would first be officially presented at USENIX in January 1993 and subsequently adopted by the Internet Engineering Task Force (IETF) in RFC 2277 (BCP 18) for future internet standards work, replacing Single Byte Character Sets such as Latin 1 in older RFCs. UTF 8 results in fewer internationalization issues Spellings with a space e. g. "UTF 8" should not be used. The official Internet Assigned Numbers Authority also lists csUTF8 as the only alias, which is rarely used. In Windows, UTF 8 is codepage 65001 (i. e. CP UTF8 in source code). In MySQL, UTF 8 is called utf8mb4 (with utf8mb3, and its alias utf8, being a subset encoding for characters in the Basic Multilingual Plane). In HP PCL, the Symbol ID for UTF 8 is 18N. In Oracle Database (since version 9.0), AL32UTF8 means UTF 8. See also CESU 8 for an almost synonym with UTF 8 that rarely should be used. UTF 8 BOM and UTF 8 NOBOM are sometimes used for text files which contain or do not contain a byte order mark (BOM), respectively. In Japan especially, UTF 8 encoding without a BOM is sometimes called UTF 8N.
Размещение кода страницы
В следующей таблице суммируется использование кодовых единиц UTF-8 (отдельных байтов или октетов) в формате кодовой страницы. Верхняя половина предназначена для байтов, используемых только в однобайтовых кодировках, поэтому она выглядит как обычная кодовая страница; нижняя половина – для байтов продолжения и ведущих байтов, и её описание приведено в легенде ниже.
Оверлонговые кодировки
В принципе, можно увеличить количество байтов в кодировании, добавляя ведущие нули к кодовой точке. Чтобы закодировать знак евро € из приведенного выше примера четырьмя байтами вместо трех, его можно дополнить ведущими нулями до длины 21 бит, и закодировать как (или в шестнадцатеричном виде). Это называется "чрезмерно длинной" кодировкой. Стандарт определяет, что корректная кодировка кодовой точки использует только минимальное количество байтов, необходимое для хранения значимых бит этой кодовой точки. Более длинные кодировки называются "чрезмерно длинными" и не являются допустимыми представлениями кодовой точки в UTF-8. Это правило обеспечивает взаимно однозначное соответствие между кодовыми точками и их допустимыми кодировками, то есть для каждой кодовой точки существует единственная допустимая кодировка. Это гарантирует корректность сравнения и поиска строк.
, and encoded as (or in hexadecimal). This is called an overlong encoding. The standard specifies that the correct encoding of a code point uses only the minimum number of bytes required to hold the significant bits of the code point. Longer encodings are called overlong and are not valid UTF 8 representations of the code point. This rule maintains a one to one correspondence between code points and their valid encodings, so that there is a unique valid encoding for each code point. This ensures that string comparisons and searches are well defined.
Усыновление
UTF-8 является наиболее распространенной кодировкой для Всемирной паутины с 2008 года. По состоянию на 2024 год UTF-8 используется 98,2% опрошенных веб-сайтов, и даже утверждается, что "UTF-16 – это уникальная проблема, которую Windows создает для кода, предназначенного для работы на нескольких платформах".
Однобайтовый
UTF-8 может кодировать любой символ Unicode, избавляя от необходимости определять и устанавливать "кодовую страницу" или иным образом указывать используемый набор символов, и позволяет одновременно выводить текст, написанный разными системами письменности. Для многих систем письменности использовалось несколько однобайтовых кодировок, поэтому даже знания о системе письменности было недостаточно для правильного отображения текста. Байты 0xFE и 0xFF не встречаются в UTF-8, поэтому корректная последовательность UTF-8 никогда не совпадает с маркером порядка байтов (BOM) UTF-16 и, следовательно, не может быть с ней перепутана. Отсутствие 0xFF (0377) также устраняет необходимость экранирования этого байта в Telnet (и FTP-соединении управления). Текст, закодированный в UTF-8, занимает больше места, чем специализированные однобайтовые кодировки, за исключением простых символов ASCII. В случае систем письменности, которые использовали 8-битные наборы символов с нелатинскими символами, закодированными в старшей половине (например, большинство кодовых страниц кириллицы и греческого алфавита), символы в UTF-8 будут занимать вдвое больше места. Для некоторых систем письменности, таких как тайский и деванагари (используемый в различных языках Южной Азии), символы будут занимать втрое больше места. Существуют даже примеры, когда один байт преобразуется в составной символ в Unicode и, следовательно, в UTF-8 занимает в шесть раз больше места. Это вызвало протесты в Индии и других странах. В UTF-8 (или любой другой многобайтовой кодировке) строку можно разделить или усечь посередине символа. Если эти две части не будут соединены обратно перед интерпретацией как символы, это может привести к появлению недопустимой последовательности в конце предыдущего фрагмента и в начале следующего, и некоторые декодеры не сохранят эти байты, что приведет к потере данных. Однако, поскольку UTF-8 является самосинхронизирующимся, это никогда не приведет к появлению другого допустимого символа, а также довольно легко переместить точку усечения назад к началу символа. Если кодовые точки имеют одинаковый размер, измерение фиксированного их количества выполняется легко. Из-за документации эпохи ASCII, где "символ" используется как синоним "байта", это часто считается важным. Однако, измеряя позиции строки в байтах, а не в "символах", большинство алгоритмов можно легко и эффективно адаптировать для UTF-8. Например, поиск строки в длинной строке можно выполнять побайтово; свойство самосинхронизации предотвращает ложные срабатывания.
Другие многобайтовые
UTF-8 может кодировать любой символ Unicode. Файлы, использующие разные системы письменности, могут отображаться корректно без необходимости выбирать правильную кодовую страницу или шрифт. Например, китайский и арабский языки можно записать в одном файле без специальной разметки или ручных настроек, определяющих кодировку. UTF-8 является самосинхронизирующимся: границы символов легко идентифицируются путем сканирования на предмет чётко определенных битовых шаблонов в любом направлении. Если байты теряются из-за ошибки или повреждения, всегда можно найти следующий допустимый символ и продолжить обработку. Если необходимо укоротить строку, чтобы она соответствовала заданному полю, предыдущий допустимый символ можно легко найти. Многие многобайтовые кодировки, такие как Shift JIS, гораздо сложнее пересинхронизировать. Это также означает, что для работы с UTF-8 можно использовать алгоритмы поиска строк, ориентированные на байты (поскольку символ эквивалентен "слову", состоящему из определенного количества байтов), а оптимизированные версии поиска по байтам могут быть значительно быстрее благодаря аппаратной поддержке и таблицам поиска, содержащим всего 256 записей. Однако самосинхронизация требует резервирования битов для этих маркеров в каждом байте, что увеличивает размер. Кодирование эффективно выполняется с помощью простых побитовых операций. UTF-8 не требует более медленных математических операций, таких как умножение или деление (в отличие от Shift JIS, GB 2312 и других кодировок). UTF-8 занимает больше места, чем многобайтовая кодировка, разработанная для конкретной системы письменности. Восточноазиатские устаревшие кодировки обычно используют два байта на символ, в то время как в UTF-8 на символ приходится три байта.
UTF-16
Байтовые кодировки и UTF-8 представлены байтовыми массивами в программах, и часто не требуется никаких изменений в функциях при преобразовании исходного кода из байтовой кодировки в UTF-8. UTF-16 представлен массивами 16-битных слов, и для преобразования в UTF-16 с сохранением совместимости с существующими программами на основе ASCII (как это было сделано в Windows) требуется дублирование каждого API и структуры данных, принимающих строку: одна версия принимает байтовые строки, а другая – UTF-16. Если обратная совместимость не нужна, все операции обработки строк всё равно должны быть изменены. Текст, закодированный в UTF-8, будет меньше, чем тот же текст, закодированный в UTF-16, если количество кодовых точек ниже U+0080 больше, чем в диапазоне U+0800 – U+FFFF. Это верно для всех современных европейских языков. Это часто верно даже для таких языков, как китайский, из-за большого количества пробелов, переносов строк, цифр и HTML-разметки в типичных файлах. Большинство средств связи (например, HTML и IP) и хранилищ (например, для Unix) были разработаны для потока байтов. Строка UTF-16 должна использовать пару байтов для каждой кодовой единицы: порядок этих двух байтов становится важным и должен быть указан в протоколе UTF-16, например, с помощью маркера порядка байтов (BOM). Если в UTF-16 отсутствует нечётное количество байтов, вся оставшаяся часть строки будет бессмысленным текстом. Любые отсутствующие байты в UTF-8 всё равно позволят точно восстановить текст, начиная со следующего символа после отсутствующих байтов.
The order of those two bytes becomes an issue and must be specified in the UTF 16 protocol, such as with a byte order mark (BOM). If an odd number of bytes is missing from UTF 16, the whole rest of the string will be meaningless text. Any bytes missing from UTF 8 will still allow the text to be recovered accurately starting with the next character after the missing bytes.
Деривативы
Следующие реализации незначительно отличаются от спецификации UTF-8. Они не соответствуют спецификации UTF-8 и могут быть отклонены приложениями, соответствующими спецификации UTF-8.
КЭСУ-8
В техническом отчете Unicode № 26 кодировке CESU 8 присвоено название, обозначающее нестандартный вариант UTF-8, в котором символы Unicode из дополнительных плоскостей кодируются шестью байтами вместо четырех, необходимых для UTF-8. Кодировка CESU 8 рассматривает каждую половину четырехбайтовой пары суррогатов UTF-16 как двухбайтовый символ UCS-2, в результате чего получается два трехбайтовых символа UTF-8, которые вместе представляют исходный символ из дополнительной плоскости. Символы Unicode, находящиеся в базовой многоязычной плоскости, отображаются так же, как и в стандартном UTF-8. Отчет был создан для признания и формализации существования данных, закодированных в CESU 8, несмотря на то, что Консорциум Unicode не рекомендует его использовать, и отмечается, что возможной причиной использования кодировки CESU 8 является сохранение бинарного порядка сортировки UTF-16. Кодировка CESU 8 может возникать при преобразовании данных UTF-16, содержащих символы из дополнительных плоскостей, в UTF-8 с использованием методов преобразования, которые предполагают данные UCS-2, то есть не учитывают четырехбайтовые символы UTF-16. Эта проблема особенно актуальна для операционных систем, активно использующих UTF-16 внутри, таких как Microsoft Windows. В Oracle Database набор символов использует кодировку CESU 8 и считается устаревшим. Рекомендуется использовать набор символов, соответствующий стандарту UTF-8. Использование CESU 8 запрещено в документах HTML5.
MySQL utf8mb3
В MySQL набор символов определяется как данные, закодированные в UTF-8, с максимальным количеством трех байт на символ, что означает поддержку только символов Unicode из базовой многоязычной плоскости (т.е. из UCS-2). Символы Unicode из дополнительных плоскостей явно не поддерживаются. устарел и заменяется на набор символов, использующий стандартную кодировку UTF-8. является псевдонимом для , но в будущей версии MySQL планируется сделать его псевдонимом для . Строки в модифицированной кодировке UTF-8 никогда не содержат фактических нулевых байт, но могут содержать все кодовые точки Unicode, включая U+0000, что позволяет обрабатывать такие строки (с добавленным нулевым байтом) традиционными функциями для строк, завершающихся нулевым байтом. Все известные реализации модифицированной UTF-8 также обрабатывают суррогатные пары в соответствии со стандартом CESU-8. В обычном режиме язык поддерживает стандартную UTF-8 при чтении и записи строк через и (если это набор символов по умолчанию для платформы или запрошено программой). Однако для сериализации объектов, а также для Java Native Interface и для встраивания константных строк в файлы классов используется модифицированная UTF-8. Формат dex, определенный Dalvik, также использует ту же модифицированную UTF-8 для представления строковых значений. Tcl также использует ту же модифицированную UTF-8, что и Java, для внутреннего представления данных Unicode, но использует строгий CESU-8 для внешних данных.
WTF-8
В WTF 8 (Wobbly Transformation Format, 8 бит) разрешены непарные суррогатные полусимволы (U+D800 – U+DFFF). Это необходимо для хранения потенциально некорректного UTF-16, например, имён файлов Windows. Многие системы, работающие с UTF-8, используют такой подход, не считая его отличной кодировкой, поскольку он проще. Термин "WTF 8" также шутливо применяется к ошибочно дважды закодированному UTF-8, иногда с намёком на то, что кодируются только байты CP1252.
PEP 383
Версия 3 языка программирования Python рассматривает каждый байт недействительной последовательности байтов UTF-8 как ошибку (см. также изменения, связанные с новым режимом UTF-8 в Python 3.7); это дает 128 различных возможных ошибок. Были разработаны расширения, позволяющие без потерь преобразовывать любую последовательность байтов, считающуюся UTF-8, в UTF-16 или UTF-32, путем преобразования 128 возможных ошибочных байтов в зарезервированные кодовые точки и обратного преобразования этих кодовых точек в ошибочные байты для вывода UTF-8. Наиболее распространенный подход заключается в преобразовании кодов в U+DC80 – U+DCFF, которые являются низкими (завершающими) суррогатными значениями и, следовательно, "недействительными" UTF-16, как это используется в подходе Python PEP 383 (или "surrogateescape"). Другая кодировка, MirBSD OPTU 8/16, преобразует их в U+EF80 – U+EFFF в области частного использования. В любом подходе значение байта кодируется в младших восьми битах кодовой точки. Эти кодировки очень полезны, поскольку они позволяют избежать работы с "недействительными" байтовыми строками до более позднего момента, если вообще это необходимо, и позволяют "текстовым" и "данным" массивам байтов быть одним и тем же объектом. Если программа хочет использовать UTF-16 внутри, ей необходимо сохранять и использовать имена файлов, которые могут содержать недействительный UTF-8; поскольку API файловой системы Windows использует UTF-16, необходимость поддержки недействительного UTF-8 там снижается. Для обеспечения обратимости кодирования стандартные кодировки UTF-8 кодовых точек, используемых для ошибочных байтов, должны считаться недействительными. Это делает кодировку несовместимой с WTF-8 или CESU-8 (хотя и только для 128 кодовых точек). При перекодировании необходимо соблюдать осторожность с последовательностями кодовых точек ошибок, которые преобразуются обратно в допустимый UTF-8, что может быть использовано вредоносным программным обеспечением для получения неожиданных символов в выходных данных, хотя это не может привести к появлению символов ASCII, поэтому считается относительно безопасным, поскольку вредоносные последовательности (например, межсайтовый скриптинг) обычно полагаются на символы ASCII.