Меню

Главная
Случайная статья
Настройки
UTF-8
Материал из https://ru.wikipedia.org

UTF-8 (от англ. Unicode Transformation Format, 8-bit — «формат преобразования Юникода, 8-бит») — распространённый стандарт кодирования символов, позволяющий более компактно хранить и передавать символы Юникода, используя переменное количество байт (от 1 до 4), и обеспечивающий полную обратную совместимость с 7-битной кодировкой ASCII. Стандарт UTF-8 официально закреплён в документах RFC 3629 и ISO/IEC 10646 Annex D.

Кодировка UTF-8 сейчас является доминирующей в веб-пространстве. Она также нашла широкое применение в UNIX-подобных операционных системах[2].

Формат UTF-8 был разработан 2 сентября 1992 года Кеном Томпсоном и Робом Пайком, и реализован в Plan 9[3]. Идентификатор кодировки в Windows — 65001[4].

UTF-8, по сравнению с UTF-16, наибольший выигрыш в компактности даёт для текстов на латинице, поскольку латинские буквы без диакритических знаков, цифры и наиболее распространённые знаки препинания кодируются в UTF-8 лишь одним байтом, и коды этих символов соответствуют их кодам в ASCII.[5][6]

Содержание

Алгоритм кодирования(сериализации)

Алгоритм кодирования в UTF-8 стандартизирован в RFC 3629 и состоит из 3 этапов:

1. Определить количество октетов, требуемых для кодирования символа. Номер символа берётся из стандарта Юникода.
Диапазон номеров символов Требуемое количество октетов
00000000-0000007F 1
00000080-000007FF 2
00000800-0000FFFF 3
00010000-0010FFFF 4


Для символов Юникода с номерами от U+0000 до U+007F (занимающими один октет c нулём в старшем бите) кодировка UTF-8 полностью соответствует 7-битной кодировке US-ASCII.

2. Установить старшие биты первого октета в соответствии с необходимым количеством октетов для кодирования символа, определённом на первом этапе:
  • 0xxxxxxx — если для кодирования потребуется один октет;
  • 110xxxxx — если для кодирования потребуется два октета;
  • 1110xxxx — если для кодирования потребуется три октета;
  • 11110xxx — если для кодирования потребуется четыре октета.


Если для кодирования требуется больше одного октета, то в октетах 2-4 два старших бита всегда устанавливаются равными 102 (10xxxxxx). Это позволяет легко отличать первый октет в потоке, от других октетов
Количество октетов Значащих бит Шаблон
1 7 0xxxxxxx
2 11 110xxxxx 10xxxxxx
3 16 1110xxxx 10xxxxxx 10xxxxxx
4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx


3. Установить значащие биты октетов в соответствии с номером символа Юникода, выраженном в двоичном виде. Начать заполнение с младших битов номера символа, поставив их в младшие биты последнего октета, продолжить справа налево до первого октета. Свободные биты первого октета, оставшиеся незадействованными, заполнить нулями.

Примеры кодирования
Символ Двоичный код символа UTF-8 в двоичном виде UTF-8 в шестнадцатеричном виде
$ U+0024 0100100 00100100 24
U+00A2 10100010 11000010 10100010 C2 A2
U+20AC 100000 10101100 11100010 10000010 10101100 E2 82 AC
U+10348 1 00000011 01001000 11110000 10010000 10001101 10001000 F0 90 8D 88


Алгоритм декодирования(десиарилизации)

Алгоритм декодирования требуется для того, чтобы преобразовать сырую последовательность октетов, в готовую для использования Юникод точку. алгоритм состоит из 3 этапов:

1. Определить длину символа в октетах. Для определения длины символа, декодер UTF-8 смотрит на служебные биты(тоесть те, которые сами по себе не несут полезной нагрузки, но при этом критически важны для определения длины символа в октетах.

служебные биты в UTF-8 всегда старшие) установленные при кодировании Юникод точки в UTF-8 символ.

если служебные биты равны 110,1110 или 11110 то текущий октет - начало символа. если служебный бит равен 0 - это ASCII символ.


если служебные биты равны 10 - текущий октет является продолжением.

2. Убрать служебные биты. Поскольку декодер UTF-8 уже определил длину символа, служебные биты больше не являются нужными, а также будут мешать этапу 3, именно поэтому декодер UTF-8 "вырезает" служебные биты из потока октетов используя побитовую операцию "И" с необходимой маской, обнуляющую служебные биты оставляя при этом биты с данными не подвергнутыми изменениям.

3. соединить изолированные биты в Юникод точку. После того, как декодер UTF-8 убрал служебные биты, его основной задачей является соединить изолированные между собой биты в Юникод точку.

Для этого декодер UTF-8 использует побитовый оператор "сдвига влево"(<<) который выполняет 2 операции:

1. перемещает младшие в кодировке UTF-8 биты на их изначальную, более старшую позицию.

2. защищает от наложений групп битов друг на друга тем, что перемещает группу битов в другое положение, оставляя свободное место для других групп битов.

После того, как декодер UTF-8 переместил младшие биты в кодировке UTF-8 в их изначальное более старшое место, он должен поместить и младшие биты исходного символа. Для этого он использует побитовую операцию "ИЛИ"(|), которая соединяет более младшую часть исходного символа, в уже существующий октет, где есть старшая часть исходного символа.

Маркер UTF-8

Для указания, что файл или поток содержит символы Юникода, в начале файла или потока может быть вставлен маркер последовательности байтов (англ. Byte order mark, BOM), который в случае кодирования в UTF-8 принимает форму трёх байтов: EF BB BF16.
1-й байт 2-й байт 3-й байт
Двоичный код 1110 1111 1011 1011 1011 1111
Шестнадцатеричный код EF BB BF


Пятый и шестой байты

Изначально кодировка UTF-8 допускала использование до шести октетов для кодирования одного символа, однако в ноябре 2003 года стандарт RFC 3629 запретил использование пятого и шестого октетов, а диапазон кодируемых символов был ограничен символом U+10FFFF. Это было сделано для обеспечения совместимости с UTF-16.

Возможные ошибки декодирования

Не всякая последовательность октетов является допустимой. Декодер UTF-8 должен понимать и адекватно обрабатывать такие ошибки:
  • Недопустимый октет.
  • октет продолжения (10xxxxxx) без начального октета.
  • Отсутствие нужного количества октетов продолжения 10xxxxxx — например, двух после 1110xxxx.
  • Строка обрывается посреди символа.
  • Неэкономное кодирование — например, кодирование символа тремя октетами, когда можно двумя. (Существует нестандартный вариант UTF-8, который кодирует символ с кодом 0 как 1100.0000 1000.0000, отличая его от символа конца строки 0000.0000.)
  • Последовательность октетов, декодирующаяся в недопустимую кодовую позицию (например символы суррогатных пар UTF-16).


Примечания
  1. https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
  2. Usage Statistics of Character Encodings for Websites, June 2011 (англ.)
  3. Архивированная копия (англ.). Дата обращения: 27 февраля 2007. Архивировано из оригинала 1 марта 2011 года.
  4. Code Page Identifiers — Windows applications | Microsoft Docs. Дата обращения: 14 июля 2018. Архивировано 16 июня 2019 года.
  5. Well, I'm Back. String Theory (англ.). Robert O'Callahan (1 марта 2008). Дата обращения: 1 марта 2008. Архивировано 23 августа 2011 года.
  6. Ростислав Чебыкин. Всем кодировкам кодировка. UTF8: современно, грамотно, удобно. HTML и CSS. Дата обращения: 22 марта 2009. Архивировано 23 августа 2011 года.


Ссылки
Downgrade Counter