为什么超市售货员扫一下条形码就能结账?为什么别人扫一下你的二维码就能加上你的微信?小小的条形码、二维码中究竟如何蕴藏如此多不同的信息?今天,就让我们和孩子们一起走进条形码、二维码的世界吧!
撰文 | 吴进远
我们讨论了摩尔斯电码,谈到它对当代的计算机技术有着深刻的影响。这种影响并不是在具体的编码方法上,而主要是体现在思维方法上。现在我们购买到的大多数商品,包装上面都有条形码。条形码初期存在多个发明,现在也存在非常多的变种。条形码可以算是和摩尔斯电码沾点边,因为早期的一位发明家曾经受到过摩尔斯电码的启示。确实,从某种意义上说,我们可以想象把摩尔斯电码的点和划,垂直画成线,变成窄和宽的条纹。当然现在主流应用上的条形码,并不是简单地从摩尔斯电码转换来的。条形码世界
今天,计算机越来越多地参与着我们生活的方方面面。为了把信息迅速方便地送入计算机,人们设计了各种各样的编码,条形码就是其中的一种。其他的编码方法,比如rfid,尽管成本越来越低,但相比之下,条形码仍然是最便宜的,其成本几乎为零,因为条形码只需要用油墨印在包装盒上即可。条形码是怎样将信息编码的呢?对于不同的应用存在许多标准。我们这里介绍一下其中一个标准,即gtin-13以及它所对应的条形码编码标准ean-13。gtin是global tradeitem number的意思,其中的gtin-13标准是用13位数字代表全球贸易中的万物。其中最高的三位代表生产物品的国家,比如中国生产的产品前三位是690-695。其余一些位数表示地域,行业等信息,靠后的一些位数是物品的代码。如果13位数全部用满,可以表述10万亿种不同的物品,足够全球所有人每人研发1000种不同的商品。我们现在在市场上买到的商品,大部分都有这样一个13位数的代码。gtin兼容了国际标准书号(isbn),国际标准期刊序号(issn)等等。当gtin-13需要印刷成条形码的时候,使用的是ean-13条形码标准。比如作者参与写作的一本科学普及书的条形码,如下图所示。对于图书,不管是哪个国家出版的,其前三位都被指定为978或979。而杂志期刊等,前三位总是977。大家可以仔细观察上面的条形码,我们可以看到数字5出现了几次,不过它们似乎长的不完全一样,在左边的两个是一个样,而在右边的两个显然不同。如果认真看看,左边与右边条纹是“黑白颠倒”的关系。可是,再看看左边出现的两个7,它们似乎也不一样。此外,在条形码左边与右边各有6位数字,这并不难理解,但整个码符号的最左边那个9是怎么来的?难道可以无中生有吗?
为此,我们需要了解一下ean-13(包括isbn,issn,upc等)条形码的生成规则。条形码的编码规则
ean-13条形码是用两个条纹来表示一个数字的,整个码包括13个数字,其中直接编码12个,左边6个右边6个,第13个用后面介绍的方法隐含编码。条形码两边与中间安排了起始符(s)中间符(m)以及结束符(e),各为两个窄条。因此,所有码,不管具体数字是什么,都包含有30个条纹。那么,每个数字又是怎样用两个条纹表示的呢?这就需要我们在更细尺度上讨论。每个数字的两个条纹,包括了两黑两白四个区域,它们的总宽度为7个单位宽度。这个单位宽度可以根据印刷精度自由选择,比如当我们把单位宽度选定为0.5毫米时,每个数字所占宽度为3.5毫米。对于左边6个数字,每个数字的左边一定是白的,而右边一定是黑的。每个数字从左到右都是“白黑白黑”地构造。这样,当几个数字一个个紧挨在一起的时候,它们之间就可以存在一个清晰的边界。了解了这些,我们就可以想象自己是当年制定这种条形码的设计师,很容易地数一数可用的编码有哪些。我们可以把7个单位宽度组合在一起,看成7个比特的二进制数。如果这7个比特可以任意安排黑白,则可以表达128个字符。不过我们已经限定最左边一定是白色,最右边一定是黑色,这样就只有中间5个比特可以改变,或者说最多可以表达32个字符。把这32个可能的字符全部画出来,就得到下面这个图。现在,我们把不符合“白黑白黑”要求的字符去掉,还剩下20个可用的字符。这20个字符又可以分成两类,一类包含有奇数个(3个或5个)单位宽度为黑,共10个,另一类包含有偶数个(2个或4个)单位宽度为黑,也是共有10个。我们把这两类字符分别用来作为0-9数字的代码。其中奇偶性为奇的10个称为ean-l码,在上面图中用浅棕色标注。奇偶性为偶地10个称为ean-g码,在上面图中用浅绿色标注。这两种左边的条形码如下图所示。
那么,右边的条形码又是什么样的呢?我们希望最终的条形码具有一定的对称性,比如希望右边的码左黑右白,这样可以与结束符(e)有一个清晰的边界。因此最简单的一个做法,是把ean-l码黑白颠倒,这样我们就有了ean-r码,如下图所示。显然,由于ean-l的奇偶性为奇,因此很容易看出ean-r的奇偶性为偶,里面黑条的总宽度为偶数个单位宽度,与ean-l正好反过来。
有了左边与右边数字的条形编码图形,我们就很容易拼接出一个完整的条形码。当我们只需要编码12个数字时,也就是说当13位数中最高位为0时,左边6个数字都用ean-l码,右边6个数字则用ean-r码。把数字与s,m,e符拼接在一起后,我们就可以得到如下图所示的条形码。
我们前面问过一个问题,在13位编码的整个条形码码符号的最左边那个数字(我们前面图书的条形码中的9)是怎么来的。此外,大家还会问,我们前面谈到的ean-g图形能不能用在条形码的左边,代替ean-l码?实际上,这两个问题是联系在一起的,ean-13中,最左边那个数字,就是利用ean-g图形,代替左边6个数字中一部分ean-l图形来表述的。
在条码左边6个数字中,每个数字可以选用l或者g两种码。因此通过选择每一位的l或g,一共可以得到64(2的6次方)种组合。人们从这64种组合中,挑出了10个组合,用来表述13位编码中的最左边那个数。这10个组合以及它们代表的数字为:0=llllll;1=llglgg;2=llgglg;3=llgggl;4=lgllgg;5=lggllg;6=lgggll;7=lglglg;8=lglggl;9=lgglgl。这样一来,最左边这个数不需要直接用一个单独的图形表述,而只需要通过选配左边6个数字编码图形的l或g组来“隐喻”。现在我们再回过头看我们前面那本书的条形码,原来的一些疑问也就豁然开朗了。首先,右边的两个5与左边的两个5自然不会是相同的,我们知道 ean-l 与 ean-r 对应的10个编码,是黑白反转的关系。那么,同在左边的相同数字编码一样吗?不一定。比如上面条码中左边的两个7,它们一个是 l 码另一个是 g 码。因为这个条码编码了第13位数字9,因此左边6个数字的l或g的选择为9=lgglgl,因此它的第一个7是l而第二个7是g,所以这两个7长得不一样。此外,我们还可以看出左边的两个5恰好都是l,否则它们也未必相同。
条形码带给我们的启示
在很多编码工作的实践中,我们的着眼点是提高编码的效率。也就是说,利用尽量少的资源来存储或者传输比较多的信息。但是在设计条形码的时候,更需要考虑的,是可靠性和准确性。为此,我们可能会“浪费”一些编码资源,来提高编码的冗余度。在前面谈到的条形码中,每个数字的编码空间有7个单位宽度,如果充分利用可以编制128个字符。但是我们对编码空间作了限制:(1)左白右黑,(2)包含两个条纹。这样一来,这个编码空间中就只剩下20个可以用的组合了。但是这样做带来的好处非常多。首先是两个数字挨在一起,它们之间存在一个黑白清晰的边界。同时在每个数字的编码空间中,也不会出现一大片黑,或者一大片白的状况,而是存在足够的黑白变化,便于扫描器辨别。更重要的是,这样的编码方法提供了很多简便的查错方法。比如一个完整的条形码,不论是什么内容,总是包含30个条纹。这样,当扫码器扫过之后如果发现多于30或少于30个条纹,立即就能知道是出错了。条形码应用中,还会出现一个常见的复杂性,就是扫码器既可能从左向右正着扫,也可能反过来扫。这就要求条形码自身携带左右标识。当我们在条形码的左边使用ean-l码,右边使用ean-r码的时候,条形码的左右就非常分明。左边所有数字的奇偶性为奇,右边所有数字的奇偶性为偶。当我们需要编制13位数编码,因此在左边6个数中有些会使用ean-g码的时候,左边有些数字的奇偶性也可能呈现偶。不过,我们前面看到,左边6个数中最左边那一位总是使用l码,这就足以作为条形码的左标识了。从条形码到二维码
条形码毫无疑问是非常成功的,但由于条形码是编码空间是一维的,因此可以携带的信息非常有限。很自然,人们想到要向平面上两个维度发展。多年来,二维的条形码出现过许多标准及变化。我们今天经常看到的一种是qr码。下图所示qr码是作者创作的一个科学普及音乐视频文件在微云上的链接。这里特意提醒一下读者,一个二维码当中,直接编码的内容是几十乃至上百个字母或数字,它们通常构成一个链接,但它们不是视频文件本身。视频文件往往会需要几十 mb 乃至几十 gb 存储空间,二维码存储不了那么多的数据。
当然,二维码要容纳几十乃至上百个字母和数字也并不容易。对比条形码,人们对二维码在可靠性和准确性上的要求是一样的。但是,二维码要比条形码容纳更多的信息,因此还必须兼顾编码的效率。这两项要求在有的情况下是矛盾的,但是在很多时候二者是相辅相成的。二维码扫码使用时通常是用手机来拍照,在手机内得到一个由像素构成的二维点阵。手机中的软件只有可靠准确地获得了二维码的高度宽度等外形参数,才能正确地读取编制在二维码中的数据。那么,怎样才能方便地获取二维码的外形参数呢?这就需要我们在设计时作出仔细的考虑。从qr码上,可以看到在左上角,右上角和左下角各有一个口字形或回字形的方块。我们应该可以猜测出,这三个方块就是为了提供二维码外形参数的。问题是,为什么需要三个方块呢?只在左上角上留一个方块行不行?我们知道手机的照相机照出来的照片是会发生形变的,如果只有一个方块,就很不容易获取二维码的高度和宽度这两个参数。如果只留两个方块,比如,保留右上角和左下角这两个方块。这好像也不行,因为在手机的照片中,软件无法去辨认哪边是上哪边是下。如果只保留左上角和右上角两个方块,则上下倒是可以区分出来了。但是由于手机照片的形变,我们只能得到二维码宽度这个参数,而很难得到高度这个参数。因此,我们现在看到的二维码里面有三个大方块。我们这里谈到的仅仅是一些最基本的考虑,实际上二维码里的学问还是不少的,这里有一个问题提供给大家思考。下面这个二维码中,只包含了一个字母“a”。既然只有一个字母,那么这个字母占据的面积应该是很小的吧?因此在整个码所占的面积中,应该大部分是空白。但是,我们并没有在上面这个二维码中看到大块的白色或黑色区域,而是到处都是错落有致,黑白相间。大家不妨想想为什么要这样设计?用什么办法可以做到这点?
孩子们在世间遇到的问题从来不会按照教科书的次序,先易后难。他们可能还没有学过二进制,但却可能在任何时候找到一个条形码或者二维码来问家长。怎样才能不被孩子问住呢?很简单,和孩子一块找一堆条形码或二维码一块研究研究,找找规律,再上网查查,定会有所收获。·
·
·
·
·
·