条形码(barcode),也可以叫做一维码,在生活中广泛存在,包括常见的UPC、EAN、ISBN等等。
你看的每本书、喝的每瓶饮料、买的每件商品,基本都可以看到它们的身影。

UPC的编码解析

UPC(universal product code,通用产品代码,通常指UPC-A) 是最早投入使用的条形码,在美国、加拿大等欧美国家使用广泛。
尽管UPC很简单,但却是实现零售业结算和库存管理自动化的基础。
本文就从UPC着手讲解条形码是如何工作的,下文中的UPC的示例摘录自《编码:隐匿在计算机软硬件背后的语言》。

通常情况下,UPC由30条不同宽度的垂直黑色条纹组成,条纹间由不同宽度的空白间隙分割开。
聪明的你一定想到了,这些条纹的含义就是条形码下方的数字,组成了该商品特有的编号。
只不过,下方的数字是方便人阅读,而条形码是方便计算机“阅读”。

例如,下图是美国Campbell公司10盎司的罐装鸡汁面包装上的UPC:

你会发现,黑色条纹粗细不均,空白间隙也是粗细不均的。
事实上,黑色条纹有四种不同的宽度,较宽的条的宽度是最细条的宽度的两倍、三倍或者四倍。空白间隙亦然。

UPC实际上是一系列的比特,如果将一个基本单位的黑色条纹看成二进制的1,将一个基本单位的空白间隙看成0,就可以露出其“庐山真面目”:

当计算机自左向右进行扫描时,它给遇到的第一个基本单位的黑条纹分配一个值为1的比特值,随后的空白间隙为0,如此下去,直到最后一个黑色条纹为止。一共会有95个比特,组成了一个UPC。对这95个比特进行分组:

起初的3个比特通常是101,称为左边护线,最右边的3个比特也是101,为右边护线,它们的作用是帮助计算机扫描仪定位。
紧挨着左边护线,以7个比特为一组,连续6组,为左边的数字;7个比特为一组,每一组代表着数字0~9中的一个数字。
接着中间是5个比特的中间护线,固定为01010。这是一种内置式的检错码。如果扫描仪在应当找到中间护线的地方没有找到它,扫描仪就认为这不是一个UPC,以此防止错误或窜改。
接下来的右边的数字跟左边数字一样,7个比特一组,共6组。

有意思的是,7个比特组成一组,才代表了10个数字。照理来说,2的7次方,共128种组合,代表10个数字绰绰有余。
这是因为,仅有少数组合的比特值,才是有意义的。而且,左边的数字和右边的数字,组合还稍有差异。
映射关系如下表:

数字 左边的编码 右边的编码
0 0001101 1110010
1 0011001 1100110
2 0010011 1101100
3 0111101 1000010
4 0100011 1011100
5 0110001 1001110
6 0101111 1010000
7 0111011 1000100
8 0110111 1001000
9 0001011 1110100

左边的编码都以0开头,以1结尾,且1的个数都是“奇数”。
右边的编码都以1开头,以0结尾,且1的个数都是“偶数”。
右边的编码是左边编码的补码:凡是1的地方都换成0,凡是0的地方都换成1。
这不是偶然,而是故意为之。如此设计,扫描仪即使从右往左边扫描,它也知道该如何处理。

另外我们还需注意到,每个代码都仅有两组连续的值为1的比特位,这就意味着每个数字对应着条形码中的两个竖条。

如此设计还提供了一种用于检测差错和数据一致性的机制,叫做奇偶校验。
如果一组比特位中含有奇数个1,就称之为奇校验;如果含有偶数个1,则为偶校验。
进行解码时,如果发现左边的编码中出现偶数个1,则一定有错。反之亦然。这提供了一种很强的容错性,在生产中意义非凡。

如此一来,30条竖条(左边护线2条竖线,右边护线2条竖线,中间护线2条竖线,左右数字各12条竖线),最终对应成了12个数字:

0  51000  01251  7

在UPC中,第一个数字(这里是0)被称为数字系统字符,不同数字代表不同大类的货物。
紧接着的5个数字是制造商代码。在上例中,51000是Campbell公司的代码。该公司产生的产品都是该代号,需要公司去申请。
再后面的5个数字(01251)是该公司的某种产品的具体编号,公司自行分配。
最后的数字(这里是7)称作模校验字符,这个字符提供了另外一种错误检验。

最后一位的模校验字符的计算方法如下。假设前11位数字分别用A-K符号代替:

A  BCDEF  GHIJK

通过公式:

3 x (A + C + E + G + I + K) + (B + D + F + H + J)

会得到一个数字T,然后对该数字T,从紧挨它并大于等于它的一个10的整倍数中减去它,其结果称为模校验字符。

在上例中,有:

3 × (0 + 1 + 0 + 0 + 2 + 1) + (5 + 0 + 0 + 1 + 5) = 3 × 4 + 11 = 23

紧挨着23并大于等于它的,还是10的整倍数,就是30, 所以最后一位数字就是30-23 = 7

这就是印在外包装上并以UPC形式编码的模校验字符,这是一种冗余措施。
如果扫描仪计算出来的模校验结果和UPC中编码中的校验字不一致,则计算机就不能将这个UPC作为一个有效值接收。

可以看到,简简单单的UPC的设计中,至少就包含了三种校验和容错机制,设计上煞费苦心:

  • 中间护线的设计
  • 左右边编码的奇偶校验
  • 最后一位的模校验字符

在维基百科上有证明: UPC可以检测出100%的单数字错误,可以检测出90%的数字换位错误。

EAN的编码解析

UPC-A(上面所讲的UPC都是指UPC-A)有多种变种,其中UPC-EEAN-13比较常用。
UPC-E是UPC-A(12位数字)的6位数字的缩短版,由于在我国不常见,这里不再介绍。重点介绍EAN-13。

EAN-13是UPC-A的超集,可以在UPC-A的首位加入一位数字0得到。EAN-13兼容UPC-A,并且将范围扩充为原来的10倍。从EAN-13的前三位数字,还可以看出生产该商品的公司所属国。
EAN(European Article Number,欧洲商品条码)依照结构可以分为EAN-13和EAN-8,但我们常说的EAN一般特指EAN-13,而EAN-8是EAN-13的8位数字缩短版。

EAN-13的编码内容,由四个部分组成:

  • 国家或地区代号: 前3位(从下图中知道,第一位数字不属于条码的一部分,是“导入位”;后面解释该位如何推导)
  • 厂商代号: 接下来4位
  • 商品代号: 接下来5位
  • 检查码: 最后1位,由公式计算得到(后面介绍,需要将新引入的第一位数字加入计算)

编码的兼容性扩展

有了UPC的基础,再来讲EAN-13就简单多了。
还记得讲UPC的时候,分了左边的编码和右边的编码吧。我们将左边的编码称为L-code,右边的编码称为R-code。现在加入一列: G-code。

数字 L-code G-code R-code
0 0001101 0100111 1110010
1 0011001 0110011 1100110
2 0010011 0011011 1101100
3 0111101 0100001 1000010
4 0100011 0011101 1011100
5 0110001 0111001 1001110
6 0101111 0000101 1010000
7 0111011 0010001 1000100
8 0110111 0001001 1001000
9 0001011 0010111 1110100

当第一位数字(导入位)不同时,左边的编码稍微调整,右边的编码保持不变(扫描仪依然可以判断是从左到右还是相反方向)。
使用L表示采用L-code的编码,R表示采用R-code的编码,G表示G-code的编码。

第一位数字 左边的6位数字编码 右边的6位数字编码
0 LLLLLL RRRRRR
1 LLGLGG RRRRRR
2 LLGGLG RRRRRR
3 LLGGGL RRRRRR
4 LGLLGG RRRRRR
5 LGGLLG RRRRRR
6 LGGGLL RRRRRR
7 LGLGLG RRRRRR
8 LGLGGL RRRRRR
9 LGGLGL RRRRRR

根据映射表,以第一位的导入位为1为例,LLGLGG表示,左边的6位数字中,1、2、4采用L-code编码,3、5、6采用G-code编码。
根据该对照表,从左边的6位数字编码,就可以反推出第一位数字是什么,这就是为什么第一位的导入位可以不计入条形码的一部分。
从第一位的导入位,也可以推出左边的6位数字该分别采用哪种编码。

检查码的兼容性扩展

检查码的计算在UPC的基础上也很好理解。UPC的部分提到,假设前11位数字分别用A-K符号代替,现在用N表示导入位:

N A BCDEF  GHIJK

公式扩展为:

3 x (A + C + E + G + I + K) + (N + B + D + F + H + J)

由于UPC中,N始终为0,因此完美兼容。
举个例子:某条形码为:977167121601X(X为校验码),计算出X。

  • 7+1+7+2+6+1=24
  • 24×3=72
  • 9+7+6+1+1+0=24
  • 72+24=96
  • 100-96=4
  • 所以最后校验码X=4。此条形码为9771671216014。

可以看出,当导入位 = 0时(等同UPC),不管编码还是检查码,EAN-13完全兼容UPC,条形码不需要更改。

EAN前三位与国家和地区的映射关系

前三位数字 国家或地区
690~699 中国
471 中国台湾
489 中国香港
958 中国澳门
450~459 490~499 日本
880 韩国
885 泰国
500~509 英国
000~019 030~039 060~139 美国
300~379 法国
400~440 德国
978~979 图书ISBN
977 期刊ISSN

ISBN是EAN-13的子集

ISBN(International Standard Book Number,国际标准书号)是非期刊书籍上的条形码,其实只是EAN-13的子集(只讨论现使用的ISBN-13)。前三位在978~979范围内。

一个ISBN有一个或一份相应的出版物与之对应。一本书的每一版或其他的变化,能够申请到一个新的ISBN。
新版本如果在原来旧版的基础上没有内容上太大的变动,在出版时不会得到新的ISBN。
当一本书同时有平装本与精装本出版时,平装本的国际标准书号不得用于精装本,反之亦然。

ISBN的编码由五个部位组成,且每部位是不定长的,有时候会使用-符号进行分割方便阅读:

  • 前三位(第一位是导入位9,前三位目前的范围是978~979)
  • 出版国家或者语言代码
  • 出版商代码
  • 书所分配到的号码
  • 最后一位为检查码(同EAN-13)

参考

  • 《编码:隐匿在计算机软硬件背后的语言》
  • 维基百科:UPC变种
  • 维基百科:EAN
  • 维基百科:ISBN
  • Andy's Barcode World

UPC、EAN、ISBN的编码介绍相关推荐

  1. JAVA采集图书的ISBN编号编码、出版社、出版时间、版次、正文语种、定价等信息

    今天分享我的一个练手项目,用来采集图书的ISBN编号编码.出版社.出版时间.版次.正文语种.定价等信息. 本项目介绍了如何使用代理IP和多线程采集公开数据,项目尚不具备使用条件,仅供学习参考. 项目需 ...

  2. AAC(高级音频编码)帧格式及编码介绍

    参考资料: AAC以adts格式封装的分析:http://wenku.baidu.com/view/45c755fd910ef12d2af9e74c.html aac编码介绍:http://wenku ...

  3. LZO和MiniLZO编码介绍

    7.4  LZO编码的识别 近年来很多游戏开始使用LZO压缩资源文件.LZO是一种高压缩比和解压速度极快的编码.LZO有多个版本,从总体上可以分为免费版和专业版.专业版除了包含免费版所有功能外,还包含 ...

  4. AAC帧格式及编码介绍

    参考资料: AAC以adts格式封装的分析:http://wenku.baidu.com/view/45c755fd910ef12d2af9e74c.html aac编码介绍:http://wenku ...

  5. python mysql 编码方式,Python3编码与mysql编码介绍

    Python3自诩解决了编码问题,但还是有一系列的坑.本文就记录下前几天遇到的python3编码问题.mysql编码问题附带介绍. python3 json串的编码 针对于包含中文的字典,如果想要正常 ...

  6. Base64 编码介绍

    前言 首先看一下Wiki 上对于Base64的介绍. Base64是一种基于64个可打印字符来表示二进制数据的表示方法. 由于2的6次方等于64,所以每6个位元为一个单元,对应某个可打印字符.三个字节 ...

  7. 常见编码介绍。一个字符在不同编码中分别占几个字节(新手向)

    目录 什么是ASCII码? 1.介绍: 2.代码演示: 什么是Unicode码? 1.介绍: 2.注意事项的代码演示: 什么是utf-8? 一个字符在不同编码中分别占几个字节? 什么是ASCII码? ...

  8. HTTP协议压缩格式和URL编码介绍

    HTTP压缩是指web服务器和浏览器之间压缩传输请求响应结果的方法,通过采用通用的压缩算法,将数据包压缩后进行传输,从而提升页面加载速度,给用户一个更好的体验. 1.HTTP压缩过程 数据包压缩的过程 ...

  9. 二维码原理与编码介绍

    一 简介 二维条码(二维码)是用某种特定的几何图形按一定规律在平面(二维方向)分布的黑白相间的图形记录数据符号信息的. 二维码是DOI(Digital Object Unique Identifier ...

  10. form表单提交编码介绍

    做java的web开发有段日子了,有个问题老是困扰着我,就是乱码问题,基本上是网上查找解决方案(网上资料真的很多),都是一大堆的介绍如何解决此类 的乱码问题,但是没几个把问题的来龙去脉说清楚的,有时候 ...

最新文章

  1. UIScrollView
  2. linux下jdk简单配置记录
  3. 又爱又恨的 Microsoft Edge!
  4. handlebars 基础
  5. Serverless 躁动背后的 5 大落地之痛
  6. 手把手教你安装VMtools
  7. 数据库:如果MySQl磁盘满了,如何解决!
  8. 使用python实现对于chineseocr的API调用
  9. 2021年上半年直播电商行业洞察
  10. Ajax 传参的两种方式
  11. html如何引入lrc文件,lrc文件怎么打开?lrc是什么文件?
  12. ISM无需授权使用的无线频率
  13. windows mysql 开启非3306端口
  14. SpringBooot
  15. 【硬件】如何使用MOS管作为开关控制?如何看懂参数?如何MOS管选型?(从原理上分析)
  16. 亚马逊补单是怎么做的?
  17. 微信输入15个句号手机会崩溃?这5种方法挽救你的聊天记录!
  18. java操作word、excel、pdf 下载添加水印
  19. Java通过HttpClient4实现Https Get/Post请求
  20. Resources异步加载

热门文章

  1. 中国大陆五级行政区划数据爬虫
  2. Spring Boot工程结构推荐
  3. ESP8266-Arduino编程实例-SHT20温湿度传感器驱动
  4. Android闹钟TimePicker,android – TimePicker getHours(),API 15中的getMinutes
  5. 图像采集——OV5640摄像头简介、硬件电路及上电控制的Verilog代码实现并进行modelsim仿真
  6. 网站敏感词命中查询处理工具
  7. 三次样条插值的缺点_三次样条插值函数
  8. ffmpeg 命令转vp9
  9. 【软件工程】结构图(SC)——期末复习用
  10. 2019百度网盘破解不限速