Введение

Тип схемы кодирования символов – хранение текста в компьютерах.

Кодирование с переменной шириной – это тип схемы кодирования символов, в котором для кодирования набора символов (репертуара символов) для представления, как правило, в компьютере, используются коды различной длины. Наиболее распространенными кодировками с переменной шириной являются многобайтовые кодировки, использующие различное количество байтов (октетов) для кодирования разных символов. (Некоторые авторы, особенно в документации Microsoft, используют термин "многобайтовый набор символов", что является неверным, поскольку размер представления является атрибутом кодировки, а не набора символов.) Ранние кодировки с переменной шириной, использующие менее одного байта на символ, иногда применялись для упаковки английского текста в меньшее количество байтов в приключенческих играх для первых микрокомпьютеров. Однако появление дисков (которые, в отличие от магнитных лент, обеспечивали произвольный доступ, позволяя загружать текст по мере необходимости), увеличение объема компьютерной памяти и универсальные алгоритмы сжатия сделали подобные приемы в значительной степени устаревшими. Многобайтовые кодировки обычно возникают из-за необходимости увеличить количество кодируемых символов, не нарушая обратную совместимость с существующими ограничениями. Например, при использовании одного байта (8 бит) на символ можно закодировать 256 возможных символов; для кодирования более 256 символов логичным выбором было бы использовать два или более байта на единицу кодирования – два байта (16 бит) позволили бы закодировать 65 536 возможных символов, но такое изменение нарушило бы совместимость с существующими системами и, следовательно, могло оказаться невозможным.

Общая структура

Поскольку целью многобайтовой системы кодирования является минимизация изменений в существующем программном обеспечении, некоторые символы должны сохранять свои существующие коды единиц, даже если другие символы имеют несколько единиц в своих кодах. В результате в кодировании с переменной шириной существует три вида единиц: одиночные, состоящие из одной единицы, ведущие, которые стоят первыми в многоединичной последовательности, и завершающие, которые стоят после в многоединичной последовательности. Программное обеспечение ввода и отображения, очевидно, должно знать о структуре многобайтовой схемы кодирования, но другому программному обеспечению обычно не нужно знать, представляет ли пара байтов два отдельных символа или только один символ. Например, четырехсимвольная строка "I♥NY" кодируется в UTF-8 следующим образом (показано в виде шестнадцатеричных значений байтов): из шести единиц в этой последовательности 49, 4E и 59 являются одиночными (для I, N и Y), является ведущей единицей, а и являются завершающими единицами. Символ сердца представлен комбинацией ведущей единицы и двух завершающих единиц. UTF-8 позволяет программе легко идентифицировать три вида единиц, поскольку они попадают в отдельные диапазоны значений. Более старые кодировки с переменной шириной обычно не так хорошо спроектированы, поскольку диапазоны могут перекрываться. Приложению для обработки текста, работающему с кодировкой переменной ширины, необходимо сканировать текст с начала всех однозначных последовательностей, чтобы идентифицировать различные единицы и правильно интерпретировать текст. В таких кодировках можно столкнуться с ложными срабатываниями при поиске строки в середине текста. Например, если шестнадцатеричные значения DE, DF, E0 и E1 могут быть как ведущими, так и завершающими единицами, то поиск последовательности из двух единиц DF E0 может дать ложное срабатывание в последовательности DE DF E0 E1, которая состоит из двух последовательных последовательностей по две единицы. Существует также опасность того, что одна поврежденная или потерянная единица может привести к неверной интерпретации большого количества многоединичных последовательностей. В кодировке с переменной шириной, где все три типа единиц не пересекаются, поиск строки всегда работает без ложных срабатываний, и (при условии, что декодер хорошо написан) повреждение или потеря одной единицы повредит только один символ.

Многобайтовые кодировки CJK

Первое использование многобайтовых кодировок было для кодирования китайского, японского и корейского языков, которые имеют большие наборы символов, значительно превышающие 256 символов. Изначально кодирование было ограничено 7 битами. Кодировки ISO 2022 JP, ISO 2022 CN и ISO 2022 KR использовали диапазон 21–7E (шестнадцатеричный) как для ведущих, так и для последующих байтов, и отличали их от однобайтовых символов, используя управляющие последовательности ISO 2022 для переключения между одно- и многобайтовым режимами. Первоначально можно было закодировать 8836 (94×94) символов, а затем и дополнительные наборы по 94×94 символов с переключением режимов. Схемы кодирования ISO 2022 для CJK до сих пор используются в Интернете. Состояниезависимость этих кодировок и значительное перекрытие делают их сложными в обработке. На платформах Unix 7-битные кодировки ISO 2022 были заменены набором 8-битных схем кодирования, Extended Unix Code: EUC JP, EUC CN и EUC KR. Вместо использования управляющих последовательностей для различения многобайтовых последовательностей и однобайтовых символов, что делало кодировки состояниезависимыми, многобайтовые последовательности обозначались установленным старшим битом, то есть находились в диапазоне 80–FF (шестнадцатеричный), в то время как однобайтовые символы находились только в диапазоне 00–7F. Ведущие и последующие байты находились в диапазоне A1–FE (шестнадцатеричный), то есть в том же диапазоне, что и в кодировках ISO 2022, но со старшим битом, установленным в 1. Эти кодировки были достаточно просты в использовании, если все разделители были символами ASCII и избегалось усечения строк до фиксированной длины, но разрыв в середине многобайтового символа все равно мог привести к серьезной порче данных. На ПК (платформах DOS и Microsoft Windows) для японского и традиционного китайского языков стали стандартом две кодировки, в которых перекрывались все однобайтовые символы, ведущие и последующие байты: Shift JIS и Big5 соответственно. В Shift JIS ведущие байты имели диапазон 81–9F и E0–FC, последующие байты – 40–7E и 80–FC, а однобайтовые символы – 21–7E и A1–DF. В Big5 ведущие байты имели диапазон A1–FE, последующие байты – 40–7E и A1–FE, а однобайтовые символы – 21–7E (все значения в шестнадцатеричном формате). Это перекрытие снова затрудняло обработку, хотя по крайней мере большинство символов имели уникальные байтовые значения (хотя, как ни странно, обратная косая черта не имела).

Кодировки Unicode с переменной шириной

Стандарт Unicode имеет два кодирования переменной ширины: UTF-8 и UTF-16 (а также кодирование фиксированной ширины – UTF-32). Изначально стандарты Unicode и ISO 10646 предполагались с фиксированной шириной, при этом Unicode – 16-битным, а ISO 10646 – 32-битным. ISO 10646 предоставил кодировку переменной ширины под названием UTF-1, в которой одиночные символы (синглетоны) имели диапазон 00–9F, ведущие единицы (lead units) – диапазон A0–FF, а замыкающие единицы (trail units) – диапазоны A0–FF и 21–7E. Из-за этого неудачного дизайна, схожего с Shift JIS и Big5 в плане перекрытия значений, создатели операционной системы Plan 9, первой полностью реализовавшей Unicode, отказались от него и заменили гораздо более удачной кодировкой переменной ширины для Unicode: UTF-8, в которой одиночные символы имеют диапазон 00–7F, ведущие единицы – диапазон C0–FD (теперь фактически C2–F4, чтобы избежать слишком длинных последовательностей и обеспечить синхронизацию с кодирующей способностью UTF-16; см. статью UTF-8), а замыкающие единицы – диапазон 80–BF. Ведущая единица также указывает, сколько замыкающих единиц следует за ней: одна после C2–DF, две после E0–EF и три после F0–F4. UTF-16 был разработан, чтобы преодолеть ограничение в 65 536 символов оригинального Unicode (1.x) без нарушения совместимости с 16-битным кодированием. В UTF-16 одиночные символы имеют диапазон 0000–D7FF (55 296 кодовых точек) и E000–FFFF (8192 кодовых точек, всего 63 488), ведущие единицы – диапазон D800–DBFF (1024 кодовых точек), а замыкающие единицы – диапазон DC00–DFFF (1024 кодовых точек, всего 2048). Ведущие и замыкающие единицы, называемые в терминологии Unicode старшими и младшими суррогатами соответственно, отображают 1024 × 1024 или 1 048 576 дополнительных символов, что позволяет кодировать 1 112 064 (63 488 кодовых точек BMP + 1 048 576 кодовых точек, представленных парами старших и младших суррогатов) кодовых точек, или скалярных значений в терминологии Unicode (суррогаты не кодируются).