- PVSM.RU - https://www.pvsm.ru -

Штрихкод — классная штука для маркировки всего на свете, от товаров до людей. Сейчас в ходу около двух десятков стандартов двумерных штрихкодов, и ещё десятки неудачных, трагически непонятых, самопальных и внутренних корпоративных вариантов, большинство из которых с треском проигрывает обычному QR-коду. Распространённость и простота реализации сделали его самым популярным среди двумерных штрихкодов, но и у него есть недостаток, характерный для всех линейных собратьев: он вмещает очень мало информации. В 2-3 килобайта можно уместить ссылку или небольшой отрывок текста, но даже небольшая картинка или обычный документ уже не влезут даже в самый большой код.
Понятно, что вместимость обычного QR-подобного квадратика можно увеличить, увеличивая размер матрицы, добавляя цвета и играясь с формой ячеек. Единого стандарта для таких расширенных кодов нет, кроме проприетарного Microsoft Tag (HCCB) [1] с неясными перспективами развития и использования. Расширение палитры и изменение пикселей также усложняет чтение кода в сложных условиях (плохая печать, цветное или недостаточное освещение), но всё равно даёт очень ограниченное увеличение ёмкости и не позволяет без боли передать даже мегабайт данных.
Хороший пример такого самодельного стандарта — Jabcode [2]
Решить проблему уже давно предложили радикально: в отличие от линейных штрихкодов, QR встречаются не только в напечатанном виде, но и на экранах устройств в приложениях и на сайтах. Значит, если чем-то в стандарте придётся поступиться, пусть это будет возможность физической печати кода — сделаем его анимированным! Таким образом моментально превращаем статичный квадратик в источник неограниченного объёма данных, которые можно будет передавать по воздуху без подключения к любым сетям. Разумеется, скорость передачи будет невысокой, и обычная считывалка QR не сможет обработать такой код, но принцип раскодирования почти тот же и изобретать велосипед не придётся.
Первой готовой и продуманной реализацией, из всех, что мне удалось найти, стал TXQR [3] от Ивана Данилюка (блог [4], GitHub [5]). В проекте есть спецификация и PoC на Go с приложением под iOS.

Сначала код TXQR просто прокручивал обычные QR-коды в цикле, а телефон старался их считать как можно точнее, получая коррекцию ошибок только при следующем повторении цикла. В тестах автор гонял файл на 13 килобайт, получив пиковую скорость 9 KB/s. В следующей итерации формат стал использовать фонтанные коды (точнее, Luby transform code [6]), чтобы через избыточность позволить выполнять коррекцию ошибок в любых фреймах, не дожидаясь прокрутки цикла:

Если вкратце, исходные данные делятся на блоки, которые рандомно XOR-ятся в закодированные блоки, которые уже отправляются в фреймы. Некоторые блоки могут не склеиваться, что уменьшает оверхед. На клиенте получаемые из фреймов блоки XOR-ятся с уже полученными данными, в итоге получается проверенная на ошибки исходная структура данных. Больше почитать можно на вики [6] и в статье [7] Ивана про переход на фонтанные коды. В общем, несмотря на существенный оверхед, скорость декодирования данных существенно возросла:

Теперь в пике TXQR выдаёт около 25 KB/s при низком уровне коррекции ошибок. Запомним это значение и перейдём к его преемнику, созданному двумя годами позже. Встречайте,
Cimbar (Color Icon Matrix bar codes) [8] ещё больше отошёл от стандарта QR-кода, сохранив только визуальное сходство. Этот формат выжимает как можно большую пропускную способность, используя сразу цвета, иконки 8х8 вместо обычных пикселей и, разумеется, анимацию. В одну клетку кодируется 4 бита информации, и еще 2 или 3 бита добавляется за счёт использования цветовой схемы (на 4 или 8 цветов), позволяя хранить до 7 бит в одной клетке:

Кодирование в cimbar происходит по алгоритму, схожему с хэшированием изображений: декодер сравнивает тайл 4х4 со словарем из 16 ожидаемых тайлов и выбирает тот, у которого оказывается самый близкий хэш. Аналогично, для каждого тайла берётся средний цвет и сравнивается со словарём ожидаемых цветов, затем выбирается ближайший. Затем полученные данные проходят проверку ошибок по комбинации кода Рида — Соломона, для фонтанных кодов используется wirehair [9]. В текущем (не окончательном) формате размер сетки 1024х1024 символа, и при использовании на маленьких экранах или с плохой камерой код не всегда читается хорошо, поэтому разработчик обдумывает вариант пожертвовать пропускной способностью в угоду универсальности.
Выглядит итоговая картинка довольно жутко и эпилептично, но позволяет добиться при обычном уровне коррекции стабильных 700-800 KB/s! Это в 32 раза быстрее чем пиковая скорость TXQR при заниженной коррекции ошибок, и в этом можно убедиться самостоятельно:
Пока проект существует как PoC, но разработчик явно хочет довести его до ума и развить в полезный стандарт. Доки и реализация на питоне лежат в основном репозитории [8], оптимизированная библиотека на C/C++ живёт отдельно [12], мобильное приложение здесь [13]. На сайте cimbar.org [10] кодировщик работает через wasm, репо найти не удалось.
Air-gapped передача данных это круто и всегда весело придумывать сценарии использования для них. Я уже попробовал передавать приложения через cimbar и вижу в этом много интересных возможностей. Если у вас тоже появились оригинальные идеи, обсудим в комментариях.
Наша компания предлагает аренду VPS [14] для совершенно любых проектов. Предлагаем широкий выбор тарифных планов, максимальная конфигурация позволит разместить практически любой проект — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe!
Автор: Mikhail
Источник [15]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/smartfony/360339
Ссылки в тексте:
[1] Microsoft Tag (HCCB): https://en.wikipedia.org/wiki/High_Capacity_Color_Barcode
[2] Jabcode: https://github.com/jabcode/jabcode
[3] TXQR: https://github.com/divan/txqr
[4] блог: https://divan.dev/
[5] GitHub: https://github.com/divan
[6] Luby transform code: https://en.wikipedia.org/wiki/Luby_transform_code
[7] статье: https://divan.dev/posts/fountaincodes/
[8] Cimbar (Color Icon Matrix bar codes): https://github.com/sz3/cimbar
[9] wirehair: https://github.com/catid/wirehair
[10] cimbar.org: https://cimbar.org/
[11] Качаем приложение: https://github.com/sz3/cfc/releases/latest
[12] живёт отдельно: https://github.com/sz3/libcimbar
[13] здесь: https://github.com/sz3/cfc
[14] VPS: https://vdsina.ru/cloud-servers?partner=habr211
[15] Источник: https://habr.com/ru/post/534412/?utm_source=habrahabr&utm_medium=rss&utm_campaign=534412
Нажмите здесь для печати.