DotCode
DotCode — двумерный матричный штрихкод (barcode), изобретённый в 2008 году[1] компанией Hand Held Products как замена устаревшему штрихкоду Code 128. В настоящее время стандартизирована организацией Ассоциация автоматической идентификации и мобильности (AIM) как «ISS DotCode Symbology Specification 4.0»[2]. DotCode представляет собой матрицу разреженных чёрных круглых точек и белых промежутков на белом фоне (на чёрном фоне точки могут быть белыми). DotCode был разработан для использования с высокоскоростными промышленными принтерами[3], где точность печати может быть низкой. Благодаря тому, что стандарт DotCode не требует сложных элементов (например, непрерывных линий или специальных фигур), его можно наносить методом лазерной гравировки или промышленными сверлильными системами.
История и стандарты
Штрихкод DotCode был изобретён в 2008 году[1] доктором Эндрю Лонгэйкером из компании Hand Held Products и стандартизирован в 2009 году[4] организацией AIM как «Bar code symbology specification – DotCode»[5]. В 2019 году спецификация была пересмотрена и утверждена в версии «ISS DotCode Symbology Specification 4.0»[2].
С DotCode связана целая серия патентов, касающихся кодирования и декодирования:
- Патент США US20090200386A1 (Hand Held Products Inc), «Machine readable 2D symbology printable on demand»[1]
- Патент США US20190130236A1 (Datalogic IP Tech SRL), «System and method for extracting bitstream data in two-dimensional optical codes»[6]
- Патент Китая CN113297872A (Fuzhou Symbol Information Technology Co ltd), «Dotcode identification method and equipment»[7]
Применение
Штрихкод DotCode может использоваться аналогично Code 128 или любому другому двумерному матричному штрихкоду. В настоящее время применяется преимущественно для кодирования данных GS1 в табачной[8][9], алкогольной и безалкогольной[10], фармацевтической и продуктовой промышленности. Основное внедрение DotCode на данный момент — в табачной отрасли[11][12].
Основные достоинства DotCode[13]:
- Полная поддержка и замена набора символов Code 128;
- Компактное кодирование 8-битовых массивов данных;
- Поддержка Unicode с функцией Extended Channel Interpretation;
- Эффективное кодирование данных GS1;
- Использование коррекции ошибок Рида — Соломона;
- Возможность нанесения кода высокоскоростными промышленными принтерами и другими методами (лазерная гравировка и др.).
Структура штрихкода
DotCode представляет данные в виде прямоугольной структуры из чёрных круглых точек и белых промежутков на белом (или белых точек на чёрном) фоне. В отличие от других двумерных штрихкодов, DotCode не содержит поисковых паттернов и должен детектироваться алгоритмами поиска областей (blob detection) — например, с помощью фильтра Габора или преобразования Хафа по окружности. Все данные, метаданные и коды коррекции ошибок кодируются в одной матрице точек, без видимых различий между их частями.
Примеры DotCode:
Символ DotCode строится из следующих элементов:[2]
- Два битовых маски (на схеме выделены зелёным);
- Информационные биты (как данные, так и коды коррекции ошибок), которые считываются сверху вниз (чётная сторона кода) и слева направо (нечётная сторона);
- Угловые маркеры (на схеме красные точки) — могут использоваться как данные или заполняющие (чёрные) точки;
- Тихая зона не менее трёх размеров точки.
Битовая последовательность DotCode:
(две битовые маски: M2, M1)(информационные биты)(угловые биты, могут быть данными или заполняющими: C1–C6)
Коды данных (codewords) в диапазоне 0–112 кодируются шаблонами 5 из 9 бит[2] — каждая девятка точек содержит 5 чёрных и 4 белых точки. Если размер матрицы не кратен 9, оставшиеся позиции заполняются дополнительными чёрными точками (padding bits)[2] (от 0 до 8). Логически массив бит выглядит так:
(2 бита маски)(кодовые слова по 9 бит)(0–8 бит заполнения)
Требования к размерам DotCode[2]:
- Сумма ширины и высоты должна быть нечётной:
- Минимальный размер матрицы — 5×5, максимум не ограничен;
- Рекомендуется выбирать размер с не менее 6 заполнителей-чёрных бит, где остаток ёмкости данных от деления на 9 больше или равен 6:[2]
Для минимизации визуальных проблемных паттернов кодовые слова данных маскируются, порождая разные комбинации точек. Маска применяется только к серии данных и не затрагивает коды коррекции ошибок. В DotCode предусмотрено 4 паттерна маскирования, кодируемых двумя битами в начале массива символа[2]:5.2.4
| Маска | Биты | Операция маски (пример: 099 099 099 099 099 099 099 099 106) |
|---|---|---|
| 0 | 00 | Прибавление 0 к каждому значению (без изменений) (000) 099 099 099 099 099 099 099 099 106 |
| 1 | 01 | Прибавление последовательных троек к значениям по модулю 113 (001) 099 102 105 108 111 001 004 007 017 |
| 2 | 10 | Прибавление последовательных семёрок по модулю 113 (002) 099 106 000 007 014 021 028 035 049 |
| 3 | 11 | Прибавление последовательных семнадцаток по модулю 113 (003) 099 003 020 037 054 071 088 105 016 |
В DotCode применяется коррекция ошибок Рида — Соломона[2] с простым числом 3 и конечным полем (GF(113)). Кодовые слова данных — это числа 0–112, а значение маски трактуется как ведущий код данных 0–3. Длина защищаемого массива составляет (1 + ND), где ND — количество кодов данных; количество кодов коррекции:
,
где NC — число кодов коррекции.
Итоговое число кодовых слов:
,
NW — общее количество символов (1 маска + ND данные + NC коррекция).
Если NW превышает 112, данные разбиваются на несколько блоков коррекции:
, где B — число блоков.
Деление на блоки производится так (для каждого блока n, n=1...B):
Данные коррекции дописываются после данных блока в перемешанном порядке[14]:
(ND)(NC1_1)(NC2_1)(NC3_1)...(NC1_n)(NC2_m)(NC3_k)
Кодирование
Размер кода DotCode не ограничен стандартом, однако на практике для размерности 100×99 (4950 точек) можно закодировать 366 исходных кодовых слов, 730 цифр, 365 алфавитно-цифровых символов или 304 байта. Информационное сообщение представлено кодовыми словами 0–112, каждое из которых кодируется шаблоном 5 из 9 бит.
Возможности кодирования DotCode[2]:
- Нативное кодирование цифр или символов ASCII (0–127) с помощью наборов A, B и C, расширенные значения (128–255) через режим Upper Shift;
- Эффективное кодирование байтов (5 байтов за 6 кода) в режиме Binary Latch;
- Поддержка кодирования данных GS1;
- Кодирование символов Unicode с функцией Extended Channel Interpretation;
- Поддержка структурированного объединения штрихкодов (Structured Append);
- Поддержка режима «Макросов» (Macros).
| Символ данных | Символ данных | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Кодовое слово | Набор A | Набор B | Набор C | Шаблон точки | Кодовое слово | Набор A | Набор B | Набор C | Шаблон точки | ||||
| Символ | ASCII | Символ | ASCII | Символ | ASCII | Символ | ASCII | ||||||
| 0 | SP | 32 | SP | 32 | 00 | 101010101 | 57 | Y | 89 | Y | 89 | 57 | 110101100 |
| 1 | ! | 33 | ! | 33 | 01 | 010101011 | 58 | Z | 90 | Z | 90 | 58 | 110110010 |
| 2 | " | 34 | " | 34 | 02 | 010101101 | 59 | [ | 91 | [ | 91 | 59 | 110110100 |
| 3 | # | 35 | # | 35 | 03 | 010110101 | 60 | \ | 92 | \ | 92 | 60 | 111001010 |
| 4 | $ | 36 | $ | 36 | 04 | 011010101 | 61 | ] | 93 | ] | 93 | 61 | 111010010 |
| 5 | % | 37 | % | 37 | 05 | 101010110 | 62 | ^ | 94 | ^ | 94 | 62 | 111010100 |
| 6 | & | 38 | & | 38 | 06 | 101011010 | 63 | _ | 95 | _ | 95 | 63 | 001011110 |
| 7 | ' | 39 | ' | 39 | 07 | 101101010 | 64 | NUL | 00 | ` | 96 | 64 | 001101110 |
| 8 | ( | 40 | ( | 40 | 08 | 110101010 | 65 | SOH | 01 | a | 97 | 65 | 001110110 |
| 9 | ) | 41 | ) | 41 | 09 | 010101110 | 66 | STX | 02 | b | 98 | 66 | 001111010 |
| 10 | * | 42 | * | 42 | 10 | 010110110 | 67 | ETX | 03 | c | 99 | 67 | 010011110 |
| 11 | + | 43 | + | 43 | 11 | 010111010 | 68 | EOT | 04 | d | 100 | 68 | 010111100 |
| 12 | , | 44 | , | 44 | 12 | 011010110 | 69 | ENQ | 05 | e | 101 | 69 | 011001110 |
| 13 | - | 45 | - | 45 | 13 | 011011010 | 70 | ACK | 06 | f | 102 | 70 | 011011100 |
| 14 | . | 46 | . | 46 | 14 | 011101010 | 71 | BEL | 07 | g | 103 | 71 | 011100110 |
| 15 | / | 47 | / | 47 | 15 | 100101011 | 72 | BS | 08 | h | 104 | 72 | 011101100 |
| 16 | 0 | 48 | 0 | 48 | 16 | 100101101 | 73 | HT | 09 | i | 105 | 73 | 011110010 |
| 17 | 1 | 49 | 1 | 49 | 17 | 100110101 | 74 | LF | 10 | j | 106 | 74 | 011110100 |
| 18 | 2 | 50 | 2 | 50 | 18 | 101001011 | 75 | VT | 11 | k | 107 | 75 | 100010111 |
| 19 | 3 | 51 | 3 | 51 | 19 | 101001101 | 76 | FF | 12 | l | 108 | 76 | 100011011 |
| 20 | 4 | 52 | 4 | 52 | 20 | 101010011 | 77 | CR | 13 | m | 109 | 77 | 100011101 |
| 21 | 5 | 53 | 5 | 53 | 21 | 101011001 | 78 | SO | 14 | n | 110 | 78 | 100100111 |
| 22 | 6 | 54 | 6 | 54 | 22 | 101100101 | 79 | SI | 15 | o | 111 | 79 | 100110011 |
| 23 | 7 | 55 | 7 | 55 | 23 | 101101001 | 80 | DLE | 16 | p | 112 | 80 | 100111001 |
| 24 | 8 | 56 | 8 | 56 | 24 | 110010101 | 81 | DC1 | 17 | q | 113 | 81 | 101000111 |
| 25 | 9 | 57 | 9 | 57 | 25 | 110100101 | 82 | DC2 | 18 | r | 114 | 82 | 101100011 |
| 26 | : | 58 | : | 58 | 26 | 110101001 | 83 | DC3 | 19 | s | 115 | 83 | 101110001 |
| 27 | ; | 59 | ; | 59 | 27 | 001010111 | 84 | DC4 | 20 | t | 116 | 84 | 110001011 |
| 28 | < | 60 | < | 60 | 28 | 001011011 | 85 | NAK | 21 | u | 117 | 85 | 110001101 |
| 29 | = | 61 | = | 61 | 29 | 001011101 | 86 | SYN | 22 | v | 118 | 86 | 110010011 |
| 30 | > | 62 | > | 62 | 30 | 001101011 | 87 | ETB | 23 | w | 119 | 87 | 110011001 |
| 31 | ? | 63 | ? | 63 | 31 | 001101101 | 88 | CAN | 24 | x | 120 | 88 | 110100011 |
| 32 | @ | 64 | @ | 64 | 32 | 001110101 | 89 | EM | 25 | y | 121 | 89 | 110110001 |
| 33 | A | 65 | A | 65 | 33 | 010010111 | 90 | SUB | 26 | z | 122 | 90 | 111000101 |
| 34 | B | 66 | B | 66 | 34 | 010011011 | 91 | ESC | 27 | { | 123 | 91 | 111001001 |
| 35 | C | 67 | C | 67 | 35 | 010011101 | 92 | FS | 28 | | | 124 | 92 | 111010001 |
| 36 | D | 68 | D | 68 | 36 | 010100111 | 93 | GS | 29 | } | 125 | 93 | 000101111 |
| 37 | E | 69 | E | 69 | 37 | 010110011 | 94 | RS | 30 | ~ | 126 | 94 | 000110111 |
| 38 | F | 70 | F | 70 | 38 | 010111001 | 95 | US | 31 | DEL | 127 | 95 | 000111011 |
| 39 | G | 71 | G | 71 | 39 | 011001011 | 96 | Shift B | CR/LF | 13/10 | 96 | 000111101 | |
| 40 | H | 72 | H | 72 | 40 | 011001101 | 97 | 2x Shift B | HT * | 09 | 97 | 001001111 | |
| 41 | I | 73 | I | 73 | 41 | 011010011 | 98 | 3x Shift B | FS * | 28 | 98 | 001100111 | |
| 42 | J | 74 | J | 74 | 42 | 011011001 | 99 | 4x Shift B | GS * | 29 | 99 | 001110011 | |
| 43 | K | 75 | K | 75 | 43 | 011100101 | 100 | 5x Shift B | RS * | 30 | (17)...(10) | 001111001 | |
| 44 | L | 76 | L | 76 | 44 | 011101001 | 101 | 6x Shift B | Shift A | Latch A | 010001111 | ||
| 45 | M | 77 | M | 77 | 45 | 100101110 | 102 | Latch B | Latch A | Shift B | 011000111 | ||
| 46 | N | 78 | N | 78 | 46 | 100110110 | 103 | 2x Shift C | 2x Shift C | 2x Shift B | 011100011 | ||
| 47 | O | 79 | O | 79 | 47 | 100111010 | 104 | 3x Shift C | 3x Shift C | 3x Shift B | 011110001 | ||
| 48 | P | 80 | P | 80 | 48 | 101001110 | 105 | 4x Shift C | 4x Shift C | 4x Shift B | 100011110 | ||
| 49 | Q | 81 | Q | 81 | 49 | 101011100 | 106 | Latch C | Latch C | Latch B | 100111100 | ||
| 50 | R | 82 | R | 82 | 50 | 101100110 | 107 | FNC1 | FNC1 | FNC1 | 101111000 | ||
| 51 | S | 83 | S | 83 | 51 | 101101100 | 108 | FNC2 | FNC2 | FNC2 | 110001110 | ||
| 52 | T | 84 | T | 84 | 52 | 101110010 | 109 | FNC3 | FNC3 | FNC3 | 110011100 | ||
| 53 | U | 85 | U | 85 | 53 | 101110100 | 110 | Upper Shift A | Upper Shift A | Upper Shift A | 110111000 | ||
| 54 | V | 86 | V | 86 | 54 | 110010110 | 111 | Upper Shift B | Upper Shift B | Upper Shift B | 111000110 | ||
| 55 | W | 87 | W | 87 | 55 | 110011010 | 112 | Binary Latch | Binary Latch | Binary Latch | 111001100 | ||
| 56 | X | 88 | X | 88 | 56 | 110100110 | * в ведущих позициях данных эти codewords используются как «Макросы» | ||||||
Основные правила кодирования сообщения:
- Начальный режим кодирования — Code Set C;
- Если в первой позиции два цифровых символа (значения 0–100), это GS1-сообщение;
- Если в первой позиции FNC1 (противоположно Code 128) или другой нецифровой код (101–112), сообщение считается НЕ GS1.
DotCode может кодировать полный 8-битный набор двумя способами:[2]
- Upper Shift: используются 2 кодовых слова на один (128–255) символ;
- Binary Latch: 1 кодовый символ «Binary Latch» и 6 кодовых слов на каждые 5 байтов.
Upper Shift позволяет кодировать расширенные ASCII (128–255) в две позиции, возвращаясь к исходному режиму:
| Тип Upper Shift | Коды | ASCII |
|---|---|---|
| Upper Shift A | 64–95 | 128–159 |
| Upper Shift B | 0–95 | 160–255 |
Binary Latch позволяет кодировать 8-битный набор и ECI-последовательности от 1 до 5 символов. При этом:
- Данные разбиваются на группы по 5 байтов (или идентификаторов ECI) — по 6 кодовых слов;
- Значения 0–258 преобразуются по основанию 259 в 6 кодов по основанию 103;
- Значения 0–255 — это собственно байты;
- 256, 257 или 258 означают ECI-последовательность на следующие 1, 2 или 3 байта;
- Кодовые слова выше 102 (от 103 до 112) останавливают текущий режим кодирования.
| Код | Операция |
|---|---|
| 103 | Прерывание: 2× Shift C |
| 104 | Прерывание: 3× Shift C |
| 105 | Прерывание: 4× Shift C |
| 106 | Прерывание: 5× Shift C |
| 107 | Прерывание: 6× Shift C |
| 108 | Прерывание: 7× Shift C |
| 109 | Завершение с Latch в набор A |
| 110 | Завершение с Latch в набор B |
| 111 | Завершение с Latch в набор C |
| 112 | Завершение: разделение символа, Latch в C |
Бинарное кодирование эффективнее начиная с трёх байтов:
| Количество байтов | Требуется кодовых слов | Кодовые слова с latch/back | Upper Shift-кодов |
|---|---|---|---|
| 1 | 2 | 4 | 2 |
| 2 | 3 | 5 | 4 |
| 3 | 4 | 6 | 6 |
| 4 | 5 | 7 | 8 |
| 5 | 6 | 8 | 10 |
DotCode поддерживает кодирование индикатора ECI двумя способами:[2]
- В режиме Binary Latch;
- Символом FNC2.
FNC2 в любой позиции (кроме конца) указывает на вставку ECI-последовательности — "\nnnnnn" (000000–811799), кодируемой одним или тремя кодовыми словами:
- Если следующий код < 40 — кодируется значение ECI 000000–000039;
- Иначе следующие три кода A, B, C: .
Любые две цифры в первой позиции маркируют символ как GS1 (в отличие от Code 128). Для кодирования «обычных» данных (не GS1), в первый символ вставляется FNC1 (опущен при декодировании)[2]. В иных позициях FNC1 служит разделителем идентификаторов приложения GS1 (символ GS, ASCII 29).
Кодовое слово 100 в наборе C кодирует идентификатор GS1 AI (17) — далее три кода даты истечения срока действия; перед расшифровкой следующих кодов вставляется GS1 AI (10):
(100)(24)(12)(30)(56)(64) → 17241230105664
Некоторые кодовые слова данных 97–100 в начальной позиции (набор B) представляют спецрежим «макросов»[2][15]. В других позициях то же слово кодирует ASCII-символ:
(Latch B)(HT) → [)>RS05GS … RSEoT
(Shift B)(HT) → [)>RS05GS … RSEoT
| Кодовое слово | В первой позиции данных | В последующих позициях | |
|---|---|---|---|
| Символ | ASCII | ||
| 97 | [)>RS05GS ... RSEoT | HT | 09 |
| 98 | [)>RS06GS ... RSEoT | FS | 28 |
| 99 | [)>RS12GS ... RSEoT | GS | 29 |
| 100 | [)>RSxx ... EoT (xx = 00-99) | RS | 30 |
| 1. Макроразвертки включают заголовок и окончание. 2. Для кодирования HT, FS, GS или RS в первой позиции используйте набор A. 3. Macros для code 100 намеренно опускает GS в начале и RS в конце, так как для некоторых значений «xx» это некорректно. | |||
DotCode поддерживает составные символы, где данные нескольких DotCode объединяются логически. Для этого применяется символ FNC2 в последней позиции данных. Если FNC2 последняя[2], предшествующие два символа (цифры или буквы) задают позицию и общее число в составе объединённого сообщения.
FNC3 в первой позиции данных маркирует сообщение как управляющее (инициализация/перепрограммирование считывателя)[2].
В иной позиции FNC3 разрывает сообщение на две логически отдельные части (до и после символа).
Ёмкость символа по codewords:
Ёмкость по данным:
Если остаётся свободное место, заполняем:
- Бинарный режим завершаем Latch к набору A (109);
- В других случаях используем слово 106 (Latch C/B).
Примечания
Литература
- ISO/IEC. ISO/IEC 15434:2019 "Information technology Automatic identification and data capture techniques Syntax for high-capacity ADC media". iso.org. International Organization for Standardization (ISO) (2019). Дата обращения: 13 июня 2024.


