[Из песочницы] Как создается Data Matrix?

43c90bf50b30458394621c7766d4d75e.pngData Matrix является двумерным матричным штрих кодом, состоящим из светлых и темных участков. С помощью такого штрих кода можно закодировать достаточно большой объем информации (2–3Кб). Часто Data Matrix применяется при маркировке небольших предметов, например микросхем, а также в пищевой, оборонной промышленности, рекламе и других сферах.Существует множество сайтов для создания таких кодов, но мне всегда было интересно, каким же образом текст превращается в набор черных и белых квадратиков? Должен же быть какой-то алгоритм?

При создании Data Matrix нам понадобится обратиться к арифметике полей Галуа и кодам Рида-Соломона. Рассмотрим этот процесс на простом примере.Прежде всего, посмотрим на структуру матрицы:

5ffde992256d4c7dbc88ca8150da3b8e.png

Состоит наша матрица из двух частей: шаблона поиска и закодированных данных. Разумеется, размер матрицы прямо пропорционален размеру входных данных. Вокруг нашего кода обязательно должна быть свободная зона, отделяющая код от остального изображения.

Возьмем какое-нибудь короткое слово, например, «Habr» (без кавычек) и создадим для него Data Matrix. Процесс состоит из двух этапов: на этапе высокоуровневого кодирования нужно получить последовательность кодов данных и кодов коррекции ошибок, а на этапе низкоуровневого кодирования — изобразить в матрице двоичное представление этих кодов.

Высокоуровневое кодированиеВ Data Matrix, как и в QR-коде, используются коды Рида-Соломона над полем Галуа 7ee03ab83499457f92302c9816d51458.gif (число 8 выбрано, поскольку каждое кодовое слово занимает в матрице 8 бит). Существует несколько неприводимых многочленов, позволяющих сгенерировать такое поле. Среди них c5d54a0ce824490598c5876cf3bd76ff.gif (в десятичном представлении 285, используется для QR-кодов) и 8d3b477c57a7447886b1f87a4caa2f31.gif (301, используется в Data Matrix).Для расчетов нам понадобится таблица степеней двойки для каждого элемента поля. Создается эта таблица довольно просто: если показатель степени af7a64bbc7894f9db2c17195c36834e5.gif, то возведение в степень выполняется как обычно. В противном случае 2a0d4c85f65a408591152fda7e6320a5.gif, после чего производится побитовое сложение по модулю 2 с десятичным представлением взятого неприводимого многочлена, если 81ff3ef198c449e1a3c6d0088231f026.gif. Например, 64650a14da574a62a2c84272e1a36dc0.gif, df74545044af49afa6f8af8416d882a6.gif и т. д.

Необходимо получить кодовое слово

ba2eba5690944dd5b56d2397d6107e97.gif,

где 826d9dbae103423ba3163aa7d6c1a60a.gif — информационный многочлен, 7aaad1ecc67c4de689c7fb7f27ff9631.gif — порождающий многочлен, 805dd553f8a541069d6eb5c511a49c25.gif — общая длина кода вместе с корректировочными, 5937415d1da24daea997b483e91d18fb.gif — количество информационных кодов (вместе с кодами отступа, о них — далее), 6e966c68c4804615b3ff2c20d9a408ef.gif — операция взятия остатка от деления.

Создадим для начала информационный многочлен. Для этого нам понадобится знать, какого размера должна быть матрица, чтобы можно было разместить все информационные коды: 2adfb1c9093d4ba9b87d184373a76c4f.pngИз таблицы видно, что для кодирования строки из 4х элементов нужно взять матрицу размером 12×12 («полезная» область — 10×10), в которую помещаются 5 кодов данных и 7 кодов коррекции.

Для символов таблицы ASCII код получается следующим образом: C=ASCII value+1. Например, для символа «H» C=72+1=73.

Подряд идущие цифры объединяются в пары, и для них C=N+130, где N — число, полученное в результате группировки. Например, если рядом стоят цифры 2 и 5, то C=25+130=155.

Поскольку элементов у нас меньше, чем должно быть (вместо пяти только четыре), необходимо добавить специальные коды отступа. Первым таким кодом всегда является 129. Последующие коды отступа, до первого кода коррекции ошибок, вычисляются так:

ff343478710a4d91b55e3d328a3c96b0.gif, где4ad0a95a3a584c4d8bb05b12a2346253.gif — псевдослучайное число, 80f918ae8f5740d68256f06e5bd685cd.gif — номер элемента.

Для слова «Habr» получаем следующую последовательность кодов: 73, 98, 99, 115, 129.

Теперь мы можем записать информационный многочлен:

2e1b48d8b9ab4ba7960a5db1657dec2f.gif

и домножить его на 7a658ad958dc4877ae9baa9f5a117fdb.gif (c772ebe2f4d14e449b21d9b831a4ca61.gif — число кодов коррекции):

49b27a5b4b0a45dbbf3489d4479b21ce.gif

Перейдем к созданию порождающего многочлена. Вычисляется он по следующей формуле:

bd31a622da794230a88776b78de3c241.gif

Начинаем перемножать скобки:

eb54271d5994406c86abceee85e0e00a.gif

2d9a242649a543cfaf5150a7107f3d3c.gif

Сложение в нашем поле определено как побитовое сложение по модулю 2. Сначала выполняется возведение в степень с помощью таблицы, затем их сложение и нахождение «логарифма» полученного числа для возврата к степеням двойки. В случае если после сложения степеней получается число, большее 254, берем его остаток от деления на aaf89c74cd8b44859a416627f91496a2.gif.

После перемножения всех скобок и возведения в степень получим:

f0bd790621504ea7b25d9612f11244f5.gif

Последняя операция, завершающая высокоуровневое кодирование, и, пожалуй, самая сложная — нахождение остатка от деления 1f85e9dfcae24c50aa4aa047d2e2a3b0.gif на 7aaad1ecc67c4de689c7fb7f27ff9631.gif:

bcf7da2138644681844dedaeca547a1f.png

Выполняется деление многочленов в столбик, но с учетом того, что вычитание, определенное точно так же, как и сложение, и умножение выполняются в поле Галуа.

Теперь мы можем записать кодовое слово 70d940c5ad4d4acca732756fa1966f56.gif полностью:

88d21d6847374e828369c4b47c02ca9f.gif

Низкоуровневое кодирование 292bb721106c4c59a025ba6d96a9752b.png Каждый из полученных выше кодов представляется в Data Matrix в виде квадрата размером 3×3 ячейки без правого верхнего уголка. 1 здесь соответствует старшему биту, 8 — младшему. Нужно заполнить такими элементами всю матрицу.a1b3b99187d34bf2b034bb25c7081079.png Приготовим сетку 10×10 (именно такого размера должна быть матрица в данном случае), на которой нарисуем контуры первых пяти элементов, как на рисунке справа. Вне зависимости от того, какого размера матрица, эти элементы всегда располагаются именно так, и никак иначе.

Остальные элементы размещаются аналогичным образом, но прежде чем нарисовать их, необходимо отметить несколько особых случаев, связанных с углами матрицы.

Если f4e3215daaba4021a4a7399267b4177a.gif, где a — сторона квадрата, то перед нами самый простой случай, когда после размещения всех элементов непоместившиеся участки просто переносятся на противоположную сторону.

Если f3b1d41c768b4baeaf6131788f1a1e16.gif, то в правом нижнем углу остается «лишний» квадратик размером 2×2, который заполняется так:

ab08c7c9d0464eb78002fd82c6fefddc.png Если abf54bfaab8647ce8f3982713a6b4a4d.gif или 05fafae4fd9f4644a8dc0bd4ead1f290.gif, то следует обратить внимание на левый нижний и правый верхний угол, особенно на нумерацию битов:

9d25fdc32d0842bbb727c0bfc2b4f2f0.png Есть еще два случая, которые возникают только при построении прямоугольных матриц, поэтому мы их опустим.Вернемся к нашей матрице и добавим все остальные элементы, а также укажем, какому кодовому слову соответствует каждый элемент. Стрелками показано, каким образом производится нумерация:

25a77f5061fe4220977e91041c6d8547.png После переноса непоместившихся элементов получаем:

6b974e6bbcfe49cbb3067af170ffa7c8.png В правом нижнем углу остался незанятый квадрат (c48553c987c3410ca36de273c261cf08.gif, что как раз соответствует такому случаю). Занесем в таблицу все наши коды в таком же порядке, в каком они идут в 70d940c5ad4d4acca732756fa1966f56.gif, и их двоичные представления:

cb55fdf4d1a54a758e50b5e3816328b8.png Аккуратно заполняем матрицу. Начнем с шаблона поиска и нижнего квадрата, а затем по очереди добавляем каждый код:

ebb16646deff4ecb83a0b8a38fa107dd.png

7c66c310353e4a0e8d189ab95dac2268.png

34f66bbdb2944a5b8f6bd037bd91e599.png

0fdedb221676415e8df0f96ddbe8e5c2.png

Итак, наш код Data Matrix готов:

674c18b5b1ed4de78b1d5cfc423f7f8f.png

© Habrahabr.ru