随笔杂谈之EAN-13条形码

背景

EAN码(英文全称:European Article Number)由前缀码、厂商识别码、商品项目代码和校验码组成。前缀码是国际EAN组织标识各会员组织的代码,我国为690-699;厂商代码是EAN编码组织在EAN分配的前缀码的基础上分配给厂商的代码;商品项目代码由厂商自行编码;校验码为了校验代码的正确性。在编制商品项目代码时,厂商必须遵守商品编码的基本原则:对同一商品项目的商品必须编制相同的商品项目代码;对不同的商品项目必须编制不同的商品项目代码。保证商品项目与其标识代码一一对应,即一个商品项目只有一个代码,一个代码只标识一个商品项目.我国的通用商品条码与其等效。我们日常购买的商品包装上所印的条码一般就是EAN码。另外,图书和期刊作为特殊的商品也采用了EAN13表示ISBN和ISSN。前缀977被用于期刊号ISSN,图书号ISBN用978为前缀,我国被分配使用7开头的ISBN号,因此我国出版社出版的图书上的条码全部为9787开头。

EAN-13码对应于GB 12904-2008《 商品条码 零售商品编码与条码表示》。相关规范不能上传,需要的同学可以站内私信。

本文源码工程文件见https://download.csdn.net/download/Lapedius/14041796

技术实现

数据组成

//1代表黑色,0代表白色
BYTE leftMargin[11] = {0};
BYTE startSymbol[3] = {1,0,1};//固定值
BYTE leftDataSymbol[42] = {0};
BYTE seperateSymbol[5] = {0,1,0,1,0};//固定值
BYTE rightDataSymbol[35] = {0};
BYTE checkDataSymbol[7] = {0};
BYTE endSymbol[3] = {1,0,1};//固定值
BYTE rightMargin[7] = {0};

EAN-13条码由上述8部分组成,分别是左空白区、起始符、左侧数据符、分隔符、右侧数据符、校验符、结束符和右空白区组成。每个区域的含义可以查看GB 12904相关章节。其中,左空白区、起始符、seperateSymbol、结束符和右空白区可以认为是固定值,或者只有有限的几种选择。我们主要做的内容是对数据进行编码和计算校验符。

生成待编码数据

char* sampleBarCode = "6920858266547";

EAN-13条码一般只支持阿拉伯数字编码。并且很多代码都可能有自己的含义,受中国物品编码中心分配和管理。
在这里插入图片描述

对数据编码

memcpy(leftDataSymbol + 0, EAN_UPC_A_SubSet[barCode[1]], 7);//12位
adjustAsASubset(leftDataSymbol + 0, barCode[1]);
memcpy(leftDataSymbol + 7, EAN_UPC_B_SubSet[barCode[2]], 7);//11位
adjustAsBCSubset(leftDataSymbol + 7, barCode[2]);
memcpy(leftDataSymbol + 14, EAN_UPC_B_SubSet[barCode[3]], 7);//10位
adjustAsBCSubset(leftDataSymbol + 14, barCode[3]);
memcpy(leftDataSymbol + 21, EAN_UPC_B_SubSet[barCode[4]], 7);//9位
adjustAsBCSubset(leftDataSymbol + 21, barCode[4]);
memcpy(leftDataSymbol + 28, EAN_UPC_A_SubSet[barCode[5]], 7);//8位
adjustAsASubset(leftDataSymbol + 28, barCode[5]);
memcpy(leftDataSymbol + 35, EAN_UPC_A_SubSet[barCode[6]], 7);//7位
adjustAsASubset(leftDataSymbol + 35, barCode[6]);

对于中国境内的编码(6开头),其每个数字编码对应的字符集已经确定,从12到7位分别对应ABBBAA。字符集A和B见代码工程。

memcpy(rightDataSymbol + 0, EAN_UPC_C_SubSet[barCode[7]], 7);//6位
adjustAsBCSubset(rightDataSymbol + 0, barCode[7]);
memcpy(rightDataSymbol + 7, EAN_UPC_C_SubSet[barCode[8]], 7);//5位
adjustAsBCSubset(rightDataSymbol + 7, barCode[8]);
memcpy(rightDataSymbol + 14, EAN_UPC_C_SubSet[barCode[9]], 7);//4位
adjustAsBCSubset(rightDataSymbol + 14, barCode[9]);
memcpy(rightDataSymbol + 21, EAN_UPC_C_SubSet[barCode[10]], 7);//3位
adjustAsBCSubset(rightDataSymbol + 21, barCode[10]);
memcpy(rightDataSymbol + 28, EAN_UPC_C_SubSet[barCode[11]], 7);//2位
adjustAsBCSubset(rightDataSymbol + 28, barCode[11]);

右侧数据统一按照字符集C进行编码。

计算校验符

//校验位
BYTE evenSum = barCode[1] + barCode[3] + barCode[5] + barCode[7] + barCode[9] + barCode[11];
BYTE oddSum = barCode[0] + barCode[2] + barCode[4] + barCode[6] + barCode[8] + barCode[10];
BYTE modResult = 10 - (evenSum * 3 + oddSum) % 10;
memcpy(checkDataSymbol, EAN_UPC_C_SubSet[modResult], 7);//1位

校验符的计算原理见标准的附录B。

显示

BYTE EAN13BarCode[113] = {0};
memcpy(EAN13BarCode + 0, leftMargin, 11);
memcpy(EAN13BarCode + 11, startSymbol, 3);
memcpy(EAN13BarCode + 14, leftDataSymbol, 42);
memcpy(EAN13BarCode + 56, seperateSymbol, 5);
memcpy(EAN13BarCode + 61, rightDataSymbol, 35);
memcpy(EAN13BarCode + 96, checkDataSymbol, 7);
memcpy(EAN13BarCode + 103, endSymbol, 3);
memcpy(EAN13BarCode + 106, rightMargin, 7);

上面是对数据进行组合。
工程中剩下的代码作用是将数据(比特数组)在界面上显示。本例工程运行后点击右键显示结果如下所示。使用条码扫描软件可以识别。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值