ИМЯ

UTF-8 - ASCII-совместимая многобайтовая юникодная кодировка

ОПИСАНИЕ

The Unicode 3.0 character set occupies a 16-bit code space. The most obvious Unicode encoding (known as UCS-2) consists of a sequence of 16-bit words. Such strings can contain—as part of many 16-bit characters—bytes such as '\0' or '/', which have a special meaning in filenames and other C library function arguments. In addition, the majority of UNIX tools expect ASCII files and can't read 16-bit words as characters without major modifications. For these reasons, UCS-2 is not a suitable external encoding of Unicode in filenames, text files, environment variables, and so on. The ISO 10646 Universal Character Set (UCS), a superset of Unicode, occupies an even larger code space—31 bits—and the obvious UCS-4 encoding for it (a sequence of 32-bit words) has the same problems.
Кодировка UTF-8 для представления Юникода и UCS лишена этих недостатков и поэтому в UNIX-подобных операционных системах используется наиболее часто.

Свойства

Кодировка UTF-8 обладает следующими полезными свойствами:
*
UCS-символы с кодами от 0x00000000 до 0x0000007f (стандартный набор US-ASCII) кодируются как байты с кодами от 0x00 до 0x7f (для совместимости с кодовой таблицей ASCII). Это означает, что файлы и строки, содержащие только 7-битные ASCII-символы, будут иметь одинаковое представление как в ASCII так и в UTF-8.
*
All UCS characters greater than 0x7f are encoded as a multibyte sequence consisting only of bytes in the range 0x80 to 0xfd, so no ASCII byte can appear as part of another character and there are no problems with, for example, '\0' or '/'.
*
Сохраняется лексикографический порядок сортировки строк как в кодировке UCS-4.
*
All possible 2^31 UCS codes can be encoded using UTF-8.
*
В кодировке UTF-8 никогда не используются байты с кодами 0xc0, 0xc1, 0xfe и 0xff.
*
Первый байт многобайтовой последовательности, представляющей один не ASCII UCS-символ, всегда находится в диапазоне от 0xc2 до 0xfd и указывает на длину многобайтовой последовательности. Все последующие байты в многобайтовой последовательности находятся в диапазоне от 0x80 до 0xbf. Это позволяет облегчить ресинхронизацию, устраняет необходимость учитывать состояние кодировки (statelessness) и делает кодировку независимой от пропущенных байтов.
*
Символы UCS, закодированные в UTF-8, могут занимать до шести байтов, однако в стандарте Юникода не определены символы выше 0x10ffff, поэтому в UTF-8 юникодные символы могут иметь максимальный размер 4 байта.

Кодирование

Приведённые ниже последовательности байтов используются для отображения символа. Конкретная последовательность зависит от номера символа в кодировке UCS:
0x00000000 - 0x0000007F:
0xxxxxxx
0x00000080 - 0x000007FF:
110xxxxx 10xxxxxx
0x00000800 - 0x0000FFFF:
1110xxxx 10xxxxxx 10xxxxxx
0x00010000 - 0x001FFFFF:
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0x00200000 - 0x03FFFFFF:
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10 xxxxxx
0x04000000 - 0x7FFFFFFF:
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10 xxxxxx 10xxxxxx
Позиции битов, обозначенные как xxx, заполняются соответствующими битами из кода символа в двоичном виде, наиболее значимый бит первый (прямой порядок байт).Используется самая короткая из возможных многобайтовых последовательностей, которые могут представить код символа.
The UCS code values 0xd800–0xdfff (UTF-16 surrogates) as well as 0xfffe and 0xffff (UCS noncharacters) should not appear in conforming UTF-8 streams. According to RFC 3629 no point above U+10FFFF should be used, which limits characters to four bytes.

Пример

Символ Юникода с кодом 0xa9 = 1010 1001 (знак авторского права) кодируется в UTF-8 как
11000010 10101001 = 0xc2 0xa9
а символ с кодом 0x2260 = 0010 0010 0110 0000 (знак неравенства) кодируется так:
11100010 10001001 10100000 = 0xe2 0x89 0xa0

Замечания к применению

Например, с помощью
export LANG=en_GB.UTF-8
пользователи должны выбрать локаль UTF-8 для включения поддержки UTF-8 в приложениях.
Программы, в которых учитывается используемая пользователем кодировка, должны всегда устанавливать локаль с помощью
setlocale(LC_CTYPE, "")
и затем проверять выражением
strcmp(nl_langinfo(CODESET), "UTF-8") == 0
to determine whether a UTF-8 locale has been selected and whether therefore all plaintext standard input and output, terminal communication, plaintext file content, filenames, and environment variables are encoded in UTF-8.
Программисты, привыкшие к однобайтовым кодировкам, таким как, US-ASCII или ISO 8859, должны учесть, что два предположения, действовавших ранее, в локалях UTF-8 не работают. Первое: один байт теперь не обязательно соответствует одному символу. Второе: современные эмуляторы терминала в режиме UTF-8 также поддерживают китайские, японские и корейские символы двойной ширины (double-width characters), а также комбинированные символы без пробелов, и вывод одного символа необязательно смещает курсор на одну позицию, как это было в ASCII. Для подсчёта количества символов и позиций курсора нужно использовать библиотечные функции, такие как mbsrtowcs(3) и wcswidth(3).
Стандартной ESC-последовательностью для переключения из схемы кодировки ISO 2022 (используется в терминалах VT100) в UTF-8 является ESC % G ("\x1b%G"). Соответственно, обратной последовательностью для переключения из UTF-8 в ISO 2022 будет ESC % @ ("\x1b%@"). Остальные последовательности ISO 2022 (такие, как переключение в наборы G0 и G1) в режиме UTF-8 не работают.

Безопасность

Стандарты Юникода и UCS требуют, чтобы генераторы UTF-8 использовали самую короткую возможную форму представления символов, то есть создание двухбайтной последовательности с первым байтом, равным 0xc0, запрещено. В стандарте Unicode 3.1 это правило расширено и запрещает программам воспринимать не самую короткую форму при вводе. Это сделано из соображений безопасности: если вводимые пользователем символы проверяются системой безопасности на возможные нарушения, то программам остаётся проверить только ASCII версии символов «/../», «;» или NUL, так как для этих символов может быть очень много не ASCII способов представления при не самом коротком кодировании в UTF-8.

Стандарты

ISO/IEC 10646-1:2000, Unicode 3.1, RFC 3629, Plan 9.

СМ. ТАКЖЕ

locale(1), nl_langinfo(3), setlocale(3), charsets(7), unicode(7)

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Azamat Hackimov <[email protected]>, Dmitriy Ovchinnikov <[email protected]>, Dmitry Bolkhovskikh <[email protected]>, Katrin Kutepova <[email protected]>, Yuri Kozlov <[email protected]> и Иван Павлов <[email protected]>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на [email protected]

Recommended readings

Pages related to utf-8 you should read also: