У обычных штрихкодов небольшая ёмкость, всего 13 цифр. Чтобы закодировать больше информации, нужно делать штрихкод шире или использовать несколько штрихкодов, что неудобно. К тому же неэффективно расходуется пространство: увеличение высоты штрихов никак не влияет на количество закодированной информации. Поэтому всё чаще стали использоваться матричные (двухмерные коды). Информация в них кодируется как по горизонтали, так и по вертикали. Самый популярный тип матричных кодов – QR-коды.
Общие сведения
QR-код состоит из тёмных и светлых квадратов (называемых модулями), расположенных в квадратной сетке. Существует четыре основные кодировки QR-кодов:
- Цифровая: только цифры
- Алфавитно-цифровая: цифры, английские буквы и несколько дополнительных символов
- Кандзи: поддерживает иероглифы
- Байтовая: произвольные данные в виде битов
В любой кодировке данные представляются в виде битов для помещения на QR-код. Различные кодировки позволяют сократить размер QR-кода. Например, если известно, что сообщение состоит только их цифр, то можно использовать меньше битов на символ, чем в случае английского текста. Один модуль (“квадратик”) кода соответствует одному биту информации: чёрный модуль – 1, светлый модуль – 0.
QR-код может быть различных версий (версии различаются размером QR-кода). Всего существует 40 версий – каждая последующая больше предыдущей на 4 модуля по горизонтали и вертикали. Самый маленький QR-код (версия 1) имеет размер 21 на 21 модуль, самый большой (версия 40) – 177 на 177 модулей. Вот одно и то же слово, закодированное в первой и сороковой версии QR-кода:
QR-код состоит из двух основных частей: служебной части, которая нужна для корректного сканирования и закодированных данных.
Служебная часть
Поисковые узоры
Большие концентрические квадраты, расположенные по углам. Три квадрата расположены в трёх углах (2 сверху и один слева внизу) Используются для обнаружения и правильной ориентации QR-кода в пространстве.
Выравнивающие узоры
Небольшие квадратики с тёмным модулем внутри. Расположение и количество определяется версией кода. Используются для дополнительной стабилизации кода, более точного размещения при декодировании и исправления перекосов изображения.
Полосы синхронизации
Вертикальная и горизонтальная полосы между поисковыми узорами. Состоят из чередующихся тёмных и белых модулей. Используются для определения размера модулей и уточнения координатной сетки.
Код маски и уровня коррекции
Вертикальная полоска слева от нижнего поискового узора в 7 модулей и горизонтальная полоска под верхним правым поисковым узором длиной 8 модулей. Также продублирована вертикальной и горизонтальной полосками снизу и справа от верхнего левого поискового узора. Содержит информацию об уровне коррекции ошибок и маске (о коррекции ошибок и маске далее).
Подробнее
Состоит из 15 модулей (8 + 7), 5 из которых содержат информацию об уровне коррекции и маске, а 10 - проверочные данные для исправления ошибок. Эта информация защищена дважды: избыточными данными для коррекции ошибок и тем, что скопирована в двух местах QR-кода. Дополнительно, на 15 бит с помощью операции xor накладывается маска 101010000010010.Один модуль справа от нижнего поискового узора (на рисунке выделен жёлтым) по правилам должен быть тёмным и не считается частью служебных данных.
Код версии
Прямоугольник 3 на 6 модулей над нижним поисковым узором. Также дублируется слева от верхнего правого поискового узора. Содержит информацию о версии QR-кода.
Пустое место вокруг
Рамка из белых модулей вокруг сетки шириной 4 модуля. Предотвращает ошибки при сканировании из-за близко расположенных других объектов.
Данные
Оставшееся пространство используется для записи данных.
Подготовка данных
Данные представляются в виде битов. Информация о кодировке (цифровая, алфавитно-цифровая, байтовая или кандзи) и длина исходных данных добавляется в начало данных.
Коррекция ошибок
QR-коды предусматривают механизм коррекции ошибок на случай, если часть изображения сотрётся или будет испорчена. Для этого генерируются избыточные проверочные данные (используются коды Рида-Соломона). Эти данные при декодировании позволяют восстановить утраченные части кода. Поддерживается четыре уровня коррекции: L-7%, M-15%, Q-25%, H-30%. В зависимости от размера данных и нужного уровня избыточности выбирается оптимальная версия QR-кода.
Соединение данных
Исходные данные и проверочные данные разбиваются на блоки (длина блока зависит от версии кода) и соединяются вместе.
Подробнее
По очереди берётся один байт информации из каждого блока данных, начиная от первого и заканчивая последним. Затем берётся по второму байту и так далее. Например, если данные состоят из двух блоков длиной два байта то результат будет:[1 байт 1 блок][1 байт 2 блок][2 байт 1 блок][2 байт 2 блок]
Когда закончатся блоки данных, то же самое делается с проверочными блоками. Итоговая последовательность данных записывается в QR-код.
Запись
Всё оставшееся после нанесения служебных символов место делится на столбики по 2 модуля. Данные заносятся “змейкой” начиная с правого нижнего модуля. Заполнение столбцов чередуется снизу-вверх а потом сверху-вниз.
Маска
После занесения данных на все модули, кроме служебных, накладывается маска: в зависимости от координат модуля, он либо меняется на противоположный, либо остаётся как есть. Маска нужна для того, чтобы убрать нежелательные части на изображении и упростить распознавание кода. Всего существует 8 различных масок.
По правилам нужно попробовать все маски, начислить штрафные баллы для каждой и выбрать оптимальную. Суть правил начисления баллов в том, что штрафуются части, которые могут помешать распознаванию: большие группы одноцветных модулей, группы, похожие на служебные, большой перекос в количестве модулей одного цвета и т. п. На практике часто начисление баллов не делается, а маска выбирается случайно.
Красивые коды
Есть интересная фишка с QR-кодами: возможность украшать их своим дизайном. Механизм коррекции ошибок позволяет QR-коду оставаться считываемым, даже если значительная часть модулей испорчена. За счёт этого можно добавить в QR-код свою картинку, надпись, логотип компании, текст, дизайнерское оформление, что угодно. При этом он всё ещё будет корректно считываться.
Поиграться на питоне можно здесь https://github.com/x-hw/amazing-qr