Как кодировка 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)
ваш пример Aݔ
, который состоит из кодовых точек Юникода U+0041 и U+0754, закодирован в UTF-8 as:
01000001 11011101 10010100
Итак, при декодировании UTF-8 знает, что первый байт должен быть 1-байтовым кодом, второй байт должен быть ведущим байтом 2-байтового кода, третий байт должен быть байтом продолжения, и так как второй байт является ведущим байтом 2-байт код, второй и третий байт вместе должны сформировать этот 2-байтовый код.
посмотреть здесь как UTF-8 кодирует кодовых точек Unicode.