Как кодировка UTF-8 идентифицирует однобайтовые и двухбайтовые символы?

недавно я столкнулся с проблемой кодировки символов, в то время как я копался в наборе символов и кодировке символов, это сомнение пришло мне на ум.Кодирование UTF-8 наиболее популярно из-за его обратной совместимости с ASCII.Поскольку UTF-8-это формат кодирования переменной длины, как он различает однобайтовые и двухбайтовые символы.Например, "Aݔ "хранится как" 410754 " (Unicode for A is 41 и Unicode for Arabic character is 0754.Как кодировка идентифицирует 41-это один символ а 0754-это еще один двухбайтовый символ?Почему он не рассматривается как 4107 как один двухбайтовый символ и 54 как один байтовый символ?

2 ответов


например, " Aݔ "хранится как "410754"

UTF-8 работает не так.

символы U + 0000 через U + 007F (он же ASCII) хранятся как одиночные байты. Они являются единственными символами, кодовые точки которых численно соответствуют их представлению UTF-8. Например, U+0041 становится 0x41 что это 0100001 в двоичной системе.

все остальные символы представлены несколькими байтами. U + 0080 через U + 07FF использует по два байта каждый, U+0800 до U+ffff в три байта, и от U+10000 до U+10FFFF использовать четыре байта каждый.

компьютеры знают, где заканчивается один символ и начинается следующий, потому что UTF-8 был разработан так, чтобы однобайтовые значения, используемые для ASCII, не перекрывались с теми, которые используются в многобайтовых последовательностях. Байты 0x00 через 0x7F используются только для ASCII и ничего больше; байты выше 0x7F используются только для многобайтовых последовательностей и ничто другое. Кроме того, байты, которые используются в начало многобайтовых последовательностей также не может происходить в любой другой позиции в этих последовательностях.

из-за этого кодовые точки должны быть закодированы. Рассмотрим следующие двоичные шаблоны:

  • 2 байта: 110xxxxx 10xxxxxx
  • 3 байта: 1110xxxx 10xxxxxx 10xxxxxx
  • 4 байта: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

количество единиц в первом байте говорит вам, сколько из следующих байтов все еще принадлежат тому же символу. Все байты, которые принадлежат к последовательности начать с 10 в двоичной системе. Чтобы кодировать символ, вы преобразуете его кодовую точку в двоичную и заполняете X.

в качестве примера: U+0754 находится между U + 0080 и U+07FF, поэтому ему нужно два байта. 0x0754 в двоичном составляет 11101010100, поэтому вы заменяете x этими цифрами:

11011101 10010100


короткий ответ:

UTF-8 предназначен для возможности однозначно определение тип каждого байт в поток текста:

  • 1-байтные коды (все и только символы ASCII) начните с 0
  • ведущие байты 2-байтовых кодов начните с двух 1 с последующим 0 (т. е. 110)
  • ведущие байты 3-байтовые коды начните с трех 1 с последующим 0 (т. е. 1110)
  • ведущие байты 4-байтовых кодов начните с четырех 1 с последующим 0 (т. е. 11110)
  • продолжение байт (всех многобайтовых кодов) начните с одного 1 и 0 (т. е. 10)

ваш пример , который состоит из кодовых точек Юникода U+0041 и U+0754, закодирован в UTF-8 as:

01000001 11011101 10010100

Итак, при декодировании UTF-8 знает, что первый байт должен быть 1-байтовым кодом, второй байт должен быть ведущим байтом 2-байтового кода, третий байт должен быть байтом продолжения, и так как второй байт является ведущим байтом 2-байт код, второй и третий байт вместе должны сформировать этот 2-байтовый код.


посмотреть здесь как UTF-8 кодирует кодовых точек Unicode.