UTF-12


Автор: Андрей Владимирович Лукьянов // © 2010 // e-mail: land@long.yar.ru


Опубликовано: 2010‑06‑15
Последняя правка: 2010-09-19

► English ►

◄ К оглавлению сайта ◄


Введение

UTF-12 — это проект системы представления символов Юникода в виде потока 12-битных блоков.

В основном UTF-12 предполагается использовать в сочетании с кодированием Base64, поскольку 12-битному блоку данных соответствует последовательность из ровно двух знаков Base64, что может быть очень удобно.

В чистом виде UTF-12 могла бы использоваться в компьютере, в котором минимально адресуемые ячейки памяти имеют размер 12 бит. В 1960‑е годы действительно существовали миникомпьютеры, в которых машинное слово было 12 бит (например, PDP-8).

В дальнейшем 12‑битные блоки данных будут называться «байтами» в кавычках, чтобы было ясно, что это не обычные 8‑битные байты. Значения «байтов» — беззнаковые.

Предлагаемая система кодирования обладает следующими свойствами:

Представление

В зависимости от значения, «байты» распределяются по типам следующим образом:

Тип «байта» Значение (hex.) Двоичное представление
(биты x — любые)
от до
одиночный 000 7BF 0yyyyyxxxxxx, где хотя бы один из битов y равен 0
начальный 7C0 BFF 011111xxxxxx или 10xxxxxxxxxx
конечный C00 FFF 11xxxxxxxxxx

Юникодовские символы от 0000 до 07BF кодируются одним 12‑битным «байтом» с тем же значением. В частности, одним «байтом» кодируются все русские буквы (а также греческие, армянские, еврейские и арабские).

Юникодовские символы от 07C0 до 10FFFF кодируются последовательностью из двух «байтов» следующим образом:

Это можно изобразить в виде следующей таблицы (используется двоичное представление):

Символ Юникода
из диапазона 0000—07BF
Символ Юникода
из диапазона 07C0—10FFFF
0 0 0 0 0 0 0 0 0 0 a a a a a a a a a a a aaaaaaaaaaabbbbbbbbbb
+ a
1
a
1
a
1
a
1
a
1
a
0
a
0
a
0
a
0
a
0
a
0
b b b b b b b b b b
0 a a a a a a a a a a a c c c c c c c c c c c c 1 1 b b b b b b b b b b
одиночный «байт» начальный «байт» конечный «байт»

Значения свыше 10FFFF непредставимы в UTF-12.

Примеры

Символ Юникода UTF-12
двоичн. 16-ричн. 8-ричн. Base64
U+0000 000000000000 000 0000 AA
U+07BF 011110111111 7BF 3677 e/
U+07C0 011111000001 111111000000 7C1 FC0 3701 7700 fB/A
U+0800 011111000010 110000000000 7C2 C00 3702 6000 fCwA
U+FEFF 011111111111 111011111111 7FF EFF 3777 7377 f/7/
U+FFFF 011111111111 111111111111 7FF FFF 3777 7777 f///
U+10000 100000000000 110000000000 800 C00 4000 6000 gAwA
U+10FFFF 101111111111 111111111111 BFF FFF 5777 7777 v///

Экономичность кодирования

Сравнение с UTF-8 и UTF-16:

Диапазон Юникода Бит на символ
от до UTF-8 UTF-12 UTF-16
0000 007F 8 12 16
0080 07BF 16 12 16
07C0 07FF 16 24 16
0800 FFFF 24 24 16
10000 10FFFF 32 24 32

Таким образом, UTF-12 является самой экономичной формой представления Юникода в диапазоне символов 0080—07BF (в этот диапазон попадают все русские, греческие, армянские, еврейские и арабские буквы), а также в диапазоне 10000—10FFFF (разные экзотические символы).

UTF-12 уступает UTF-8 в экономичности только в диапазонах 0000—007F (чистый ASCII) и 07C0—07FF (письмо нко).

Неправильные последовательности

Неправильные последовательности в UTF-12 имеют в принципе ту же природу, что и в UTF-8.

Неправильно сформированные последовательности UTF-12 возникают, например, если конечный «байт» идёт не после начального, а после другого конечного или после одиночного; или, наоборот, начальный или одиночный «байт» идут там, где ожидается конечный. Алгоритмы обработки должны обнаруживать такие ошибки.

Другой тип неправильных последовательностей — искусственно удлинённые. Формально можно закодировать юникодовские символы от 0000 до 07BF не только одним «байтом», но и двумя. Например, нулевой символ 0000 можно закодировать не только как один «байт» 000, но и как два «байта» 7С0+С00.

Также существует проблема с суррогатными па́рами (символами из диапазона D800—DFFF). Они используются в UTF-16, но в UTF-12 не нужны.

В UTF-12 искусственно удлинённые последовательности и символы из области суррогатных пар запрещены. Из этого следует, что в потоке UTF-12 не должны встречаться «байты» со значениями 7C0, 7F6 и 7F7. Там, где важна безопасность, лучше вообще не принимать какие-либо «неправильные» строки.

В нижеприведённых алгоритмах фразу «Сообщаем об ошибке» можно трактовать по-разному, например:

Алгоритм кодирования

Пусть входной поток состоит из 21‑битных юникодовских символов, а выходной поток — из 12‑битных «байтов». Начинаем цикл:

Алгоритм декодирования

Пусть входной поток состоит из 12‑битных «байтов», а выходной поток — из 21‑битных юникодовских символов. Начинаем цикл:

Представление UTF-12 в обычных компьютерах

Возможно, кто-то захочет использовать UTF-12 (в двоичном виде) для представления данных в обычных компьютерах с 8‑битным байтами (например, для более компактного хранения русских текстов). В этом случае предлагается следующая система:

Пусть у нас текст состоит из трёх латышских букв ģ (код 0123): ģģģ. UTF-12 в файле из 8‑битных байтов будет выглядеть так:

12‑битные «байты» 1 2 3 1 2 3 1 2 3
8‑битные байты 1 2 3 1 2 3 1 2 3 0

Тот же метод можно использовать для передачи текстов UTF-12 по протоколам, рассчитанным на передачу 8‑битных байтов.

Для передачи UTF-12 по протоколам, рассчитанным на 7‑битные данные, можно использовать дополнительное кодирование Base64 — для UTF-12 это особенно удобно, поскольку один 12‑битный «байт» кодируется ровно двумя знаками Base64. Вышеприведённая последовательность ģģģ в Base64 будет выглядеть как EjEjEj.

Base64 должно кодировать 12‑битные «байты» напрямую, без промежуточного преобразования в 8‑битные байты.