关于Data Matrix 基于ECC200标准的编码原理和相关开源代码


前言

Data Matrix是一种二维码标签,可以用来储存信息,简称DM码。
在这里插入图片描述

本文记录学习Data Matrix的解码及加密,本文主要针对ECC200标准。


一、Data Matrix 的加密

1.DM码的数据编码格式

|Data codewords|Stuffing codewords| Correction codewords|

Data codewords: 从原始数据编码得到的数据字
Stuffing codewords:如果数据字区域没有填满,用来填充的字
Correction codewords: 基于数据字和填充字,用 Reed-Solomon算法来校验产生的校验字.

2.DM码原始数据编码方法

在这里插入图片描述
在这里插入图片描述
默认采用ASCLL编码方式。
数据按照以下三种可能进行编码
o 如果数据不是扩展的ASCLL码(0到127),直接将其ASCLL码加1
o 如果数据是扩展的ASCLL码(128到255),通常是转换为两个字,第一个字是235,第二个字是其ASCLL码减127。
o 如果数据是数字,每两个数字组成一个编码,将这两个数字的值加上130。

3.DM码的大小和容量

以下是DM码的大小和容量信息,可以看出数据区大小为8x8的DM码只能容纳3个byte的数据码和5个byte的校验码。
在这里插入图片描述

4.DM码填充字的生成方法

当数据字不足以填充所有的数据区域时,可以采用填充字。填充字的第一个字总是129,后面的字可以用以下公式获取。
在这里插入图片描述

o "%"代表求模,i代表第i个位置的数据

5.校验码的生成方法

相关C代码如下

/* "prod(x,y,log,alog,gf)" returns the product "x" times "y" */ 
int prod(int x, int y, int *log, int *alog, int gf) { 
if (!x || !y) return 0; 
ELSE return alog[(log[x] + log[y]) % (gf-1)]; 
} 
/* "ReedSolomon(wd,nd,nc,gf.pp)" takes "nd" data codeword values in wd[] */ 
/* and adds on "nc" check codewords, all within GF(gf) where "gf" is a */ 
/* power of 2 and "pp" is the value of its prime modulus polynomial */ 
void ReedSolomon(int *wd, int nd, int nc, int gf, int pp) { 
int i, j, k. *log,*alog,*c; 
/* allocate, then generate the log & antilog arrays: */ 
log = malloc(sizeof(int) * gf); 
alog = malloc(sizeof(int) * gf); 
log[0] = 1-gf; alog[0] = 1; 
for (i = 1; i < gf; i++) { 
alog[i] = alog[i-1] * 2; 
if (alog[i] >= gf) alog[i] ^= pp; 
log[alog[i]] = i; 
} 
/* allocate, then generate the generator polynomial coefficients: */ 
c = malloc(sizeof(int) * (nc+1)); 
for (i=1; i<=nc; i++) c[i] = 0; c[0] = 1; 
for (i=1; i<=nc; i++) { 
c[i] = c[i-1]; 
for (j=i-1; j>=1; j--) { 
c[j] = c[j-1] ^ prod(c[j],alog[i],log,alog,gf); 
} 
c[0] = prod(c[0],alog[i],log,alog,gf); 
} 
/* clear, then generate "nc" checkwords in the array wd[] : */ 
for (i=nd; i<=(nd+nc); i++) wd[i] = 0; 
for (i=0; i<nd; i++) { 
k = wd[nd] ^ wd[i] ; 
for (j=0; j<nc; j++) { 
wd[nd+j] = wd[nd+j+l] ^ prod(k,c[nc-j-1],log, alog,gf); 
} 
} 
free(c); 
free(alog); 
free(log); 
}

6.DM码的布置

根据你的数据大小,参考标准DataMatrix国际标准ISO16022-2006进行布置。
在这里插入图片描述
在这里插入图片描述
相关布置算法如下

#include <stdio.h> 
#include <alloc.h> 
int nrow, ncol, *array; 
/* "module" places "chr+bit" with appropriate wrapping within array[] */ 
void module(int row, int col, int chr, int bit) 
{ if (row < 0) { row += nrow; col += 4 - ((nrow+4)%8); } 
if (col < 0) { col += ncol; row += 4 - ((ncol+4)%8); } 
array[row*ncol+col] = 10*chr + bit; 
} 
/* "utah" places the 8 bits of a utah-shaped symbol character in ECC200 */ 
void utah(int row, int col, int chr) 
{ module(row-2,col-2,chr,1); 
module(row-2,col-1,chr,2); 
module(row-1,col-2,chr,3); 
module(row-1,col-1,chr,4); 
module(row-1,col,chr,5); 
module(row,col-2,chr,6); 
module(row,col-1,chr,7); 
module(row,col,chr,8); 
} 
/* "cornerN" places 8 bits of the four special corner cases in ECC200 */ 
void corner1(int chr) 
{ module(nrow-1,0,chr,1); 
module(nrow-1,1,chr,2); 
module(nrow-1,2,chr,3); 
module(0,ncol-2,chr,4); 
module(0,ncol-1,chr,5); 
module(1,ncol-1,chr,6); 
module(2,ncol-1,chr,7); 
module(3,ncol-1,chr,8); 
} 
void corner2(int chr) 
{ module(nrow-3,0,chr,1); 
module(nrow-2,0,chr,2); 
module(nrow-1,0,chr,3); 
module(0,ncol-4,chr,4); 
module(0,ncol-3,chr,5); 
module(0,ncol-2,chr,6); 
module(0,ncol-1,chr,7); 
module(1,ncol-1,chr,8); 
} 
void corner3(int chr) 
{ module(nrow-3,0,chr,1); 
module(nrow-2,0,chr,2); 
module(nrow-1,0,chr,3); 
module(0,ncol-2,chr,4); 
module(0,ncol-1,chr,5); 
module(1,ncol-1,chr,6);
module(2,ncol-1,chr,7); 
module(3,ncol-1,chr,8); 
} 
void corner4(int chr) 
{ module(nrow-1,0,chr,1); 
module(nrow-1,ncol-1,chr,2); 
module(0,ncol-3,chr,3); 
module(0,ncol-2,chr,4); 
module(0,ncol-1,chr,5); 
module(1,ncol-3,chr,6); 
module(1,ncol-2,chr,7); 
module(1,ncol-1,chr,8); 
} 
/* "ECC200" fills an nrow x ncol array with appropriate values for ECC200 */ 
void ECC200(void) 
{ int row, col, chr; 
/* First, fill the array[] with invalid entries */ 
for (row=0; row<nrow; row++) { 
for (col=0; col<ncol; col++) { 
array[row*ncol+col] = 0; 
} 
} 
/* Starting in the correct location for character #1, bit 8,... */ 
chr = 1; row = 4; col = 0; 
do { 
/* repeatedly first check for one of the special corner cases, then... */ 
if ((row == nrow) && (col == 0)) corner1(chr++); 
if ((row == nrow-2) && (col == 0) && (ncol%4)) corner2(chr++); 
if ((row == nrow-2) && (col == 0) && (ncol%8 == 4)) corner3(chr++); 
if ((row == nrow+4) && (col == 2) && (!(ncol%8))) corner4(chr++); 
/* sweep upward diagonally, inserting successive characters,... */ 
do { 
if ((row < nrow) && (col >= 0) && (!array[row*ncol+col])) 
utah(row,col,chr++); 
row -= 2; col += 2; 
} while ((row >= 0) && (col < ncol)); 
row += 1; col += 3; 
/* & then sweep downward diagonally, inserting successive characters,... */ 
+ 
do { 
if ((row >= 0) && (col < ncol) && (!array[row*ncol+col])) 
utah(row,col,chr++); 
row += 2; col -= 2; 
} while ((row < nrow) && (col >= 0)); 
row += 3; col += 1; 
/* ... until the entire array is scanned */ 
} while ((row < nrow) || (col < ncol)); 
/* Lastly, if the lower righthand corner is untouched, fill in fixed pattern */ 
if (!array[nrow*ncol-1]) { 
array[nrow*ncol-1] = array[nrow*ncol-ncol-2] = 1; 
} 
} 
/* "main" checks for valid command line entries, then computes & displays array 
*/ 
void main(int argc, char *argv[]) 
{ int x, y, z; 
if (argc =< 3) { 
printf("Command line: ECC200 #_of_Data_Rows #_of_Data_Columns\n");
} ELSE { 
nrow = ncol = 0; 
nrow = atoi(argv[1]); ncol = atoi(argv[2]); 
if ((nrow >= 6) && (~nrow&0x01) && (ncol >= 6) && (~ncol&0x01)) { 
array = malloc(sizeof(int) * nrow * ncol); 
ECC200(); 
for (x=0; x<nrow; x++) { 
for (y=0; y<ncol; y++) { 
z = array[x*ncol+y]; 
if (z == 0) printf(" WHI"); 
ELSE if (z == 1) printf("BLK"); 
ELSE printf("%3d.%d",z/10,z%10); 
} 
printf("\n"); 
} 
free(array); 
} 
} 
}

二、相关开源算法

libdmtx - Open Source Data Matrix Software under a Simplified BSD license with an alternate
waiver option, The non-library components related to libdmtx are distributed under a different license(typically LGPLv2)
DataMatrix reading and writing library, utils and wrappers · GitHub
huBarcode- huBarcode is a Python Library to generate 1D and 2D Barcodes. Open source, BSD,GPL or Apache Licensed.
GitHub - hudora/huBarcode: huBarcode is a Python Library to generate 1D and 2D Barcodes
ZXing- is/was a Java library. the C++ port is no longer maintained and has been removed from the official ZXing repo.
GitHub - glassechidna/zxing-cpp: ZXing C++ Library


总结

本文总结了DM 码基于ECC200标准的编码原理,以及编码解码的相关开源代码。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值