Согласно статье в Википедии , UTF-8 имеет такой формат:
Первый код Последний код Байты Байт 1 Байт 2 Байт 3 Байт 4 точка точка используется U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 07FF 2 110xxxxx 10xxxxxx U + 0800 U + FFFF 3 1110xxxx 10xxxxxx 10xxxxxx U + 10000 U + 1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx x означает, что этот бит используется для выбора кодовой точки.
Это тратит два бита на каждый байт продолжения и один бит в первом байте. Почему кодировка UTF-8 не кодируется следующим образом?
Первый код Последний код Байты Байт 1 Байт 2 Байт 3 точка точка используется U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 3FFF 2 10xxxxxx xxxxxxxx U + 0800 U + 1FFFFF 3 110xxxxx xxxxxxxx xxxxxxxx
Он сохранит один байт, когда кодовая точка находится вне базовой многоязычной плоскости или если кодовая точка находится в диапазоне [U + 800, U + 3FFF].
Почему UTF-8 не кодируется более эффективно?
Ответы:
Это сделано для того, чтобы вы могли определить, когда находитесь в середине многобайтовой последовательности. Глядя на данные UTF-8, вы знаете, что если вы видите
10xxxxxx
, что вы находитесь в середине многобайтового символа, и вам следует выполнять резервное копирование в потоке, пока вы не увидите ни то,0xxxxxx
ни другое11xxxxxx
. Используя вашу схему, байты 2 или 3 могут легко получить паттерны типа0xxxxxxx
или11xxxxxx
Также имейте в виду, что объем сохраняемых данных полностью зависит от того, какой тип строковых данных вы кодируете. Для большей части текста, даже азиатского текста, вы редко, если когда-либо увидите четырехбайтовые символы с обычным текстом. Кроме того, наивные оценки людей о том, как будет выглядеть текст, часто ошибочны. У меня есть текст, локализованный для UTF-8, который включает строки на японском, китайском и корейском языках, но на самом деле русский язык занимает больше места. (Поскольку в наших азиатских строках часто встречаются латинские буквы с собственными именами, пунктуацией и т. Д., А среднее китайское слово составляет 1-3 символа, а среднее русское слово - много, много больше.)
источник
Официальный способ позволяет декодеру знать, когда он находится в середине кортежа, и он знает, как пропускать байты (или идти назад), пока байт не начинается с
0
или11
; это предотвращает значения мусора, когда один байт поврежден.источник
Короткий ответ: в вашем предложении не проводится различие между первым байтом и байтами продолжения.
Битовая комбинация в верхнем конце первого байта говорит вам, сколько байтов содержит фактический символ. Эти шаблоны также обеспечивают распознавание ошибок при разборе строки. Если вы читаете (казалось бы) первый байт символа и получаете 10xxxxxx, то вы знаете, что вы не синхронизированы.
источник
То, что не было упомянуто, - то, что, если у вас есть правильная последовательность кодовых точек и указатель, который гарантированно указывает на первый байт кодовой точки, с UTF-8 вы можете очень легко найти указатель на первый байт предыдущей кодовой точки (пропустите все байты, которые начинаются с 01xx xxxx). С вашей кодировкой это невозможно без потенциальной проверки всех байтов до начала строки.
Рассмотрим последовательности (2n + 2) байтов
и
Если у вас есть указатель на первый байт первой кодовой точки после этой последовательности, вы должны проверить все байты, чтобы выяснить, является ли последняя кодовая точка 0xxxxxxx или (10xxxxxx, 0xxxxxxx).
На самом деле существуют более эффективные схемы кодирования, где переход к предыдущей кодовой точке может выполняться за постоянное время, а указатели на середину кодовой точки могут быть зафиксированы. Разрешить следующие коды:
Если один из предыдущих трех байтов равен ≥ 236, то это начало 3-байтовой последовательности, поскольку в любой допустимой 3-байтовой последовательности не может быть двух таких байтов. В противном случае, если один из двух предыдущих байтов равен ≥ 128, то это начало двухбайтовой последовательности. В противном случае предыдущий байт представляет собой один байт <128.
Поиск подстроки становится немного сложнее. Возможно, вы захотите исключить нулевые байты, чтобы строка содержала нулевой байт, только если она содержит нулевую кодовую точку.
источник