原文地址:http://blog.csdn.net/FuWaer/article/details/1770317
EAN-13编码规则
英文原文地址:http://www.barcodeisland.com/ean13.phtml
翻译者:FuWaer
翻译时间:2007年8月31日
演示程序:http://blog.csdn.net/FuWaer/archive/2007/09/05/1772966.aspx
EAN-13背景知识
Ean-13是由欧洲的International Article Numbering Association(EAN)在UPC-A标准的基础上建立的。之所以要建立EAN-13,很大程度上是因为UPC-A标准并不能很好的满足国际化应用,当然,也可能是由于没有多少人愿意让美国来主宰任何事情(FuWaer译注:UPC-A标准是美国制定的),特别是欧洲人:)
EAN-13是UPC-A的一个超集。这就意味着,任何能够读取EAN-13符号的软件或硬件,都能够自动地读取UPC-A符号。EAN-13和UPC-A的唯一区别在于它们的数字系统编码不同,UPC-A是从0到9的一位数字,而EAN-13的数字系统编码由从00到99的两位数字构成,它实际上是一个国家编码。每个国家拥有为其权限范围内的公司指定厂商编码的编码权利。厂商编码仍旧和商品编码一样是5位,校验码可以采用相同的方式进行精确的计算。
Note:由于EAN-13是UPC-A的超集,并且相对于UPC-A编码来说,EAN-13处理起来更方便,不需要任何额外的工作,因此,建议所有新的设计都给予EAN-13来实现而非UPC-A。正如前面提到的那样,这样做既能保证和UPC-A的兼容性,又将让你的软件或硬件能够应对国际化交流。否则,你的设计将只能在美国和加拿大使用。另外,UCC组织已经宣布,从2005年1月1日起,美国和加拿大的所有条码系统必须能够处理EAN-13条码,以便那些国际厂商不再需要为他们供应到北美的商品打印一个不同的条码。
下图就是一个典型的EAN-13的条码:
UPC-A符号和EAN-13服务的唯一区别在于:EAN-13的数制码是2位,而UPC-A的数制码是1位。从展现形式上来看,在EAN-13中,可读的校验位位于条码的下方,而在UPC-A中,校验位是被放在了整个条码的右边,从技术层面来说,这并没有什么本质的区别,完全取决于编码本身的规定罢了。
Note:实际上,一个UPC-A符号就是第一个数制位被设置为0的EAN-13符号。例如,“075678164125”是一个UPC-A码,如果使用EAN-13对它进行编码,将是“0075678164125”。可以看出来,我们只是在前面加了一个前导的“0”。在下图中,上面的那个是UPC-A符号,下面的那个是EAN-13符号,注意看它们之间的不同。
乍一看就能知道这两个条码是不同的。在UPC-A中,条码的左右各有一个数字(左边的0是数制,右边的5是校验位),条码的下面是两组5位数(分别代表厂商编码和产品编码)。在EAN-13中,条码的右边没有校验位,而条码下面的数字是由两组6位数组成。
但是,请仔细看条码本身,也就是仔细观察组成这两个条码的“条”(FuWaer译注:黑色的竖条)和“空间”(FuWaer译注:黑色竖条之间的空白)。正如你看到的那样,在UPC-A和EAN-13中,他们的“条”和“空间”是完全相同的。唯一的区别在于可读的数字的位置不同。逻辑上,如果一个UPC-A条码是EAN-13的子集的话,那么,一个UPC-A符号的EAN-13表示形式就应该和原来的UPC-A完全相同。如上图就是这种情况。
一个EAN-13条码的组成
一个EAN-13条码被划分成了4个区域:1)数制2)厂商码3)商品码4)校验位。通常,第一个数制位被打印在条码的左边,第二个数制位被作为条码下方左手边的那组六位数的第一个字符打印,厂商码是条码下方左手边的后5位数,产品码是条码下方右手边的前五位数,校验位是条码下方右手边的最后一位。
数制:数制是由2位组成的(有些时候是3位),用来区分国家或经济区域制定厂商码的编码权利。任何以0开始的数制都是一个UPC-A条码。下表给出了有效的数值码:
此处省略了原文中的一张表,需要的话可以从英文原文中找到
厂商码:厂商码是由数制码标示的编码管理局为每个厂商分配的一个唯一的编码。一个公司的所有产品将使用相同的厂商码。
EAN使用的是“变长厂商码”。如果向UCC以前那样为厂商码分配固定的5位,将意味着每个厂商可以最多拥有99999个产品码,但是很多厂商并没有那么多的产品,对于只有少量产品的厂商来说,正将意味着几百个甚至几千个产品码将被浪费掉。因此,如果某个厂商知道自己只由少量产品的话,EAN可以给它分配一个较长的厂商码,只留少量的空间作为产品码。这样就能更加有效的利用可用的厂商码和产品码。
产品码:产品码是厂商分配的唯一编码。和厂商码不同,产品码不需要UCC分配,厂商可以为他们的每个产品自由的分配产品码而不需要考虑任何其他的组织。既然UCC已经确保了厂商码的唯一性,厂商只需要确保他们自己的产品码不重复就是了。
校验位:校验位是一个附加的位,用来验证一个条码是否被正确的扫描。扫描可能产生不正确的数据,这可能是由于不一致的扫描速度、不完善的打印或一系列其他的问题造成的,因此,有必要验证条码的其余数据已经被正确的诠释。校验位是从条码中其余的数字位中计算得到的。通常,如果校验位和基于已经扫描得到的数据计算出来的校验位的值相同的话,就可以高度的信任条码已经被正确扫描。计算校验位的方法将在本页的后面讨论。
EAN-13(和UPC-A)的编码
EAN-13(和UPC-A)条码的编码过程是相对直截了当的。要把一个值编码为EAN-13条码,需要首先计算出校验码,整个条码,包括校验位,将被编码为一个“条”和“空间”的序列。
Note:编码一个UPC-A符号和编码一个EAN-13是完全相同的,只需要在UPC-A码前面加一个“0”(例如,如果条码是075678164125,在这个码的前面加一个0就得到了EAN-13符号0075678164125)。
计算校验位
EAN-13符号被编码前,软件必须计算出正确的校验码位,校验码位也将出现在条码中。校验码位是数制、厂商码和产品码的每个数位的数值的加权和对10取模得到的。In simple English,那一位着我们必须为条码计算校验码值。首先,我们取出值得最右边一个数位并将它作为一个“奇数”字符。然后,我们从右向左移动,交替出现奇数和偶数。接下来,我们将所有偶数位置上的数值求和,将所有奇数位置上的数值乘以3后求和。
计算校验位的步骤如下:
1. 将最右边一个数位作为“奇数”位,从右向左为每个字符指定奇数/偶数位。
2. 对所有奇数位上的数值求和,将结构乘以3。
3. 对所有偶数位上的数值求和。
4. 对第2步和第3步计算的结果求和。
5. 校验位的数字加上用第4步计算的总和数应该能够被10整除。
6. 如果第4步计算的总和数能够被10整除,校验位就是“0”(不是10)
通过一个例子可以很容易理解。我们要计算条码0075678164125的校验码位。事实上,我们知道这个条码的最右一位数字“5”就是校验码位。这就是说这个条码自身的“信息”实际上是007567816412(我们是把条码的最后一个字符去掉了的)。其中,“00”是数制,“75678”是厂商码,“16412”是产品码。因此,我们必须为消息007567816412计算一个校验位。
为每个数位计算加权和,我们可以得到0+0+7+15+6+21+8+3+6+12+1+6=85。这就是校验码值。然而,只有一个校验码位。校验位的值必须能够使得校验码的值加上校验位的值能够被10整除。在这种情况下,在85之后能被10整除的数字是90。我们需要给85加上5才能得到90,因此,我们的校验位就是“5”。我们为原来的条码消息(007567816412)追加校验码位(5),就得到了最终的0075678164125。
将这个最终得到的条码和我们原来的条码比较,我们发现我们计算出来的校验码位事实上和原来条码上的校验码位是相同的。因此,我们的计算是正确的。
Note:可能你要问在EAN-13符号中,为什么第一个字符被作为了“偶数”位而第二个字符被作为了“奇数”位。逻辑上认为第一个字符应该被作为“奇数”而第二个字符应该被作为“偶数”。别担心,这里面有个合理的解释。
这样做是为了保持和原来UPC-A格式的兼容性。原来的UPC-A符号仅有单一的一位数值,因此,EAN-13符号中的第二个字符就应该是UPC-A符号中的第一个字符,因此,也就成了“奇数”位。为了不改写和混淆规范,当定义EAN-13标准的时候,他们只是在前面插入了这个新的前导字符并将它称为“偶数”位,这样就和现有的UPC-A条码保持了兼容性,在某种程度上,也兼容了现有的UPC-A的文档。
**这里省略了原文中提供的javascript计算校验码位的部分。
编码符号
既然校验码位已经计算出来了,我们知道,整个消息必须被编码为“条”和“空间”。继续使用我们例子,我们将为值0075678164125编码EAN-13条码。
在接下来的描述中,我们将用数字“1”来表示条码的一个“暗”或“条”部分,而用“0”来表示条码的一个“亮”或“空间”部分。这样,数值1101就表示一个两个宽度的条(11),跟着一个宽度的空间(0),跟着一个宽度的条(1)。这个在条码中可能被打印为下图所示:
一个EAN-13条码拥有如下物理结构:
l 左手边警戒条,或开始哨,编码为101。
l 数制码的第二个字符,按照下面描述的方式编码。
l 厂商码的5个字符,按照下面描述的方式编码。
l 中间警戒模式,编码为01010。
l 产品码的5个字符,按照下面描述的右手边字符方式进行编码。
l 校验位,按照下面描述的右手边字符方式进行编码。
l 右手边警戒条,或结束哨,编码为101。
中间警戒模式左边的字符被作为符号的“左手边”而中间警戒模式右边的字符被作为符号的“右手边”。
EAN-13数制码的第一个字符(也就是EAN-13值得一个个数位)将被编码为符号左手边字符的奇偶性上。这就是说,EAN-13值的第一个字符的值决定了条码左手边字符将按照下表中的哪种奇偶性来编码。
Note:对于“左手边编码”来说,奇偶性经常使用“字符集A”(奇)和“字符集B”(偶)来表示。
EAN字符集编码表
这个表说明了EAN-13条码中的每个数位应该如何编码,这要取决于这个数位位于条码的哪半边(左边还是右边)。在这种情况下,一个左手边数位的编码(奇数性还是偶数性)将取决于数制码的第一个数位的值(见下表中奇偶性编码)。
观察发现:
l 一个EAN-13字符使用7个元素来描述,包含2个条和2个空间。任何条或空间的长度都不会超过4个元素。唯一的例外情况就是左警戒条和右警戒条(都是3个元素)以及中间警戒条(5个元素长)。
l 条码左手边的所有字符总是以0(空间)开始的,而条码右手边的所有字符都是以1(条)开始的。
l 如果把1变成0,把0变成1,那么“右手边”编码模式和“左手边奇数”编码模式是完全相同的。
l “左手边偶数”编码模式是基于“左手边奇数”编码模式的。为了得到偶数编码,可以按照如下步骤对左手边编码模式进行操作:1)把所有的1变成0,0变成1。2)将得到的结果编码反着读(从右到左)就得到了“左手边偶数”编码模式。
EAN奇偶性编码表
下表说明了条码左手边每个字符按照哪种奇偶性进行编码。奇偶性取决于EAN-13值得第一个数位。例如,我们的CD的EAN-13值是0075678164125。在这个条码中,数制码的第一个数位就是第一个“0”,所以,奇偶性就应该遵循下表中的数字0一行:
观察得到:
l 第二个数制位总是按照奇数性进行编码(这在解码时很重要)。
l 一个UPC-A条码的第一个数制位总是0,因此,全部使用奇数性。实际上,任何第一个数值位是0的EAN-13幅好其实是一个UPC-A符号,而不是一个EAN-13符号。
l 所有EAN-13符号(那些第一个数制位不是0的)始终有3个左手边字符采用偶数性编码,有2个采用奇数性编码。
最后那两个表是EAN-13编码的关键和核心,并且兼容现有的UPC-A符号。
编码示例
这个例子将对值“7501031311309”进行EAN-13编码。“75”是数制,“01031”是厂商码,“31130”是产品码(“9”是校验位,在本例中我们还是要进行计算)。这是墨西哥的12盎司一听的百事可乐上的条码。
首先,我们计算校验位:
计算加权和7+15+0+3+9+1+9+1+3+3+0=51。我们需要给51加上9以保证能整除10(51+9=60),因此,校验位就是9。这和我们在条码后面看到的那个“9”是一致的,说明我们计算对了。
接下来,我们观察数制码的第一个数位(条码中最左边的那个数位)是数字“7”。参照奇偶性编码表中的数字“7”,我们可以知道第二个数制位和厂商码应该按照“奇/偶/奇/偶/奇/偶”的模式进行编码。这就是说第二个数制位将按照“左手边奇数”性表进行编码,厂商码的第一个数位应该按照“左手边偶数”性编码的,等等。现在,我们可以按照如下步骤来编制条码。之后将所有字符串连接起来就构成了最终的条码。
记住,一个“1”代表一个条,一个“0”代表一个空间。因此,我们可以将这个数字字符串转换成他们的图形表示形式,最终我们可以得到如下条形码:
为了能够更清晰的看出条码的构造,下图就是刚才那个条码,只是,在这张图上,每个字符或者说每个段,使用了交替的颜色来加以区分。在这个条码上,每个有颜色的段都对应着1到15种的一步,它覆盖了上面所描述的所有“步骤”。你可以用每一步的1-0序列和下面的图形进行对比: