ECI (расширенная интерпретация каналов)
ECI (Extended Channel Interpretation) — служебный сегмент QR-кода, который прямо объявляет декодеру кодировку данных. Без него байты читаются как Latin-1, и кириллица превращается в «кракозябры».
Что такое ECI
ECI (Extended Channel Interpretation, расширенная интерпретация каналов) — служебный механизм символик штрихового кодирования, который позволяет внутри самого кода объявить, в какой кодировке записаны идущие следом данные. Это не содержимое, а метка о том, как содержимое читать.
Ближайшая аналогия — HTTP-заголовок Content-Type: text/html; charset=utf-8. Байты на проводе одни и те же, но без объявления браузер трактует их наугад, и результат зависит от настроек. ECI играет ровно ту же роль для полезной нагрузки QR: превращает догадку декодера в инструкцию.
Механизм общий для целого семейства двумерных символик — QR, Data Matrix, Aztec, PDF417. Номера кодировок ведутся в едином реестре ассоциации AIM, поэтому ECI 26 означает UTF-8 и в QR-коде, и в Data Matrix. Правила записи ECI внутри QR-символа описывает ISO/IEC 18004.
Как ECI записан в битовом потоке
ECI — это отдельный сегмент со своим четырёхбитным индикатором режима, таким же по природе, как индикаторы numeric, alphanumeric и byte. Значение индикатора ECI — 0111. Сразу за ним идёт номер кодировки, и длина этого номера плавающая:
- номер 0–127 — один байт, старший бит
0; - номер 128–16383 — два байта, начинаются с
10; - номер 16384 и выше — три байта, начинаются с
110.
На практике почти всегда работает первый вариант: UTF-8 имеет номер 26, он умещается в один байт. Итого объявление кодировки стоит 4 бита индикатора плюс 8 бит номера — двенадцать бит, полтора байта. После ECI-сегмента идёт обычный сегмент данных, чаще всего байтовый, и объявленная кодировка действует до конца символа или до следующего ECI.
Номера, которые встречаются в жизни
| Номер ECI | Кодировка | Где встречается |
|---|---|---|
| 000003 | ISO/IEC 8859-1 (Latin-1) | Значение по умолчанию для байтового режима |
| 000020 | Shift JIS | Японские системы, соседствует с режимом кандзи |
| 000022 | Windows-1251 | Формально есть в реестре, но опираться на него нельзя |
| 000026 | UTF-8 | Единственный рабочий вариант для кириллицы |
Строка про Windows-1251 требует пояснения: номер в реестре зарезервирован, но пользы от него нет — камеры смартфонов однобайтовую кириллицу не ждут. Рабочая связка для русского текста одна: ECI 26 плюс UTF-8.
Что происходит, когда ECI забыли
Если сегмента ECI в коде нет, декодер обязан считать байтовые данные записанными в Latin-1. Кириллицы в Latin-1 не существует. Двухбайтовые последовательности UTF-8 распадаются на пары латинских букв с диакритикой — так и рождается классическое «Ð Ð¾ÑÑиѻ вместо «Россия».
Почему при этом половина кодов всё-таки читается правильно? Потому что многие декодеры давно не следуют букве стандарта и включают эвристику: если байты складываются в валидную UTF-8-последовательность, значит это UTF-8. Эвристика хорошая, но не обязательная. Один сканер угадает, другой — нет, третий угадает на коротком тексте и промахнётся на длинном. Отсюда практическое правило: код проверен не тогда, когда он открылся на вашем телефоне, а тогда, когда в нём есть явное объявление кодировки.
Где ECI не поможет
Micro QR — усечённая символика, в ней ECI-сегмента нет вовсе. Всё, что выходит за пределы Latin-1, туда придётся заносить транслитерацией либо переходить на полноразмерный QR.
Второе ограничение — старое промышленное оборудование. Сканер, который попал на склад полтора десятка лет назад и с тех пор не видел обновлений прошивки, может отбросить неизвестный сегмент и прочитать байты как Latin-1. Итог тот же, что и без ECI. Если аудитория кода — терминалы сбора данных, а не смартфоны, безопаснее не класть кириллицу внутрь символа вовсе: закодируйте короткий URL, а русский текст отдайте страницей. Проверяется это только опытом — соберите тестовый код в генераторе QR-кодов и прогоните по всему парку сканеров.
Частые вопросы
Чем ECI отличается от кодировки UTF-8?
Это разные уровни. UTF-8 — сама кодировка: правило, по которому «Р» превращается в байты D0 A0. ECI — способ сообщить декодеру, что перед ним именно UTF-8. Записать UTF-8-байты без ECI можно, код будет валидным и, скорее всего, прочитается за счёт эвристики сканера, но формально его интерпретация не определена. Работают эти вещи только в паре.
Насколько ECI увеличивает размер QR-кода?
На двенадцать бит — полтора байта. На фоне типичной ссылки в 30–60 байт это почти не заметно и версию символа обычно не поднимает. Реальный прирост даёт не метка, а сам UTF-8: каждая кириллическая буква занимает два байта вместо одного. Экономить на объявлении кодировки бессмысленно — платите вы за буквы.
Мой генератор не даёт настроить ECI. Что делать?
Сначала проверьте, не добавляет ли он объявление сам: многие библиотеки включают ECI автоматически, как только во входной строке появляется символ вне ASCII. Раскодируйте готовый код инструментом, который показывает структуру сегментов. Если объявления нет и настройки тоже нет — меняйте библиотеку на ту, где кодировка задаётся явно, либо убирайте кириллицу из полезной нагрузки.
Можно ли поставить несколько ECI в одном коде?
Да, ECI действует до следующего такого же сегмента, поэтому интерпретацию допустимо переключать несколько раз. На практике так почти не делают: разбирать мозаику из кодировок умеют не все декодеры, а UTF-8 покрывает нужные алфавиты сразу. Куда чаще ECI соседствует с переключением режимов кодирования.