背景
UCC/EAN-128用于商品的物流环节,非定长,用AI加数据的方式表示商品更多的辅助信息。UCC/EAN-128是code-128码的一个子集,在起始符后紧跟一个FNC1以区别于普通的CODE-128条码。
UCC/EAN-128对应于GB/T 15425-2002《 EAN.UCC系统 128条码》。相关规范不能上传,需要的同学可以站内私信。
本文源码工程文件见https://download.csdn.net/download/Lapedius/14041796
技术实现
数据组成
const unsigned short leftMargin = 0x00;//固定值
const unsigned short startSymbol = UCC_CharSetA[103];//START A固定值
const unsigned short fncSymbol = UCC_CharSetA[102];//FNC1 固定值
unsigned short dataSymbol[16];
unsigned short checkSymbol;
const unsigned short endSymbol = 0x18EB;//STOP固定值
const unsigned short rightMargin = 0x00;//固定值
UCC/EAN-128条码由上述7部分组成,分别是左空白区、起始符、FNC1、数据符、校验符、结束符和右空白区组成。每个区域的含义可以查看GB/T 15425相关章节。其中,左空白区、起始符、FNC1、结束符和右空白区可以认为是固定值,或者只有有限的几种选择。我们主要做的内容是对数据进行编码和计算校验符。
生成待编码数据
//生成随机数作为barcode
BYTE randomCode[8];
srand((unsigned int)time(NULL));
for (index = 0; index < 8; index++) {
randomCode[index] = rand() & 0xFF;
} //随机数转换为字符串,大写字母和数字混合
char sampleBarCode[32] = { 0 };
convertByteArrayToHexStr(randomCode, 8, (BYTE*)sampleBarCode);
BYTE barCodeLen = 16;
CString str = _T("条码值:");
str += CA2T(sampleBarCode);
UCC/EAN-128条码支持大写字母、小写字母、数字、特殊字符等编码。我们的例子只支持大写字母和数字混编,因此只实现了字符集A。这里是通过生成随机数,并转换为HEX形式,作为待编码的原始数据。
对数据编码
for (index = 0; index < barCodeLen; index++)
{
if (sampleBarCode[index]>= '0' && sampleBarCode[index] <= '9')//number
{
dataSymbol[index] = UCC_CharSetA[sampleBarCode[index] - '0' + 16];
}
else if (sampleBarCode[index] >= 'A' && sampleBarCode[index] <= 'Z')//character
{
dataSymbol[index] = UCC_CharSetA[sampleBarCode[index] - 'A' + 33];
}
else//not support
{
MessageBox(_T("暂时不支持!"));
return;
}
}
参照字符集A对大写字母和数据进行混合编码。字符集A见代码工程。
计算校验符
BYTE weight[32] = {1};
for (index = 1; index < 32; index++)
{
weight[index] = index;
}
WORD sum = 0;
sum = 103 * weight[0] + 102 * weight[1];//暂时只支持startA
for (index = 0; index < 16; index++)
{
if (sampleBarCode[index] >= '0' && sampleBarCode[index] <= '9')//number
{
sum += weight[index + 2] * (sampleBarCode[index] - '0' + 16);
}
else if (sampleBarCode[index] >= 'A' && sampleBarCode[index] <= 'Z')//character
{
sum += weight[index + 2] * (sampleBarCode[index] - 'A' + 33);
}
else//not support
{
MessageBox(_T("暂时不支持!"));
return;
}
}
checkSymbol = UCC_CharSetA[sum % 103];
校验符的计算原理见标准的附录C。
显示
工程中剩下的代码作用是将数据转化为比特数组,最终在界面上显示。本例工程运行后点击左键显示结果如下所示。使用条码扫描软件可以识别。