08275-6hc03idqlxf.png?x-oss-process=style/load
二维码是怎么生成的?

现在,二维码几乎无处不见,甚至菜市场的大妈都会使用二维码来进行移动支付。
58027-1uv0x2ed81vg.png?x-oss-process=style/load
在二维码,即矩阵码大家庭中,不仅仅有我们常用的QR code 二维码,还有很多类似的矩阵码,如Aztec、Data Matrix、MaxiCode等等,他们的前身是超市中仍在使用的一维条码。

那么二维码是如何生成的?又如何被识别?

我们主要讨论QR code,即 Quick Response code (快速响应代码)。为了方便给你讲解,我会在后面直接叫它二维码。由于二维码的生成涉及了非常广的知识方面,我的表述无法完全正确,请谅解。

52964-cet1bmfbgq.png?x-oss-process=style/load
这是两个二维码,对比它们,可以看到左上、右上和左下都有一个回字型方块,这是二维码的定位图案。

20827-34xgpr0ze3r.png?x-oss-process=style/load
得益于它,我们可以在扫描二维码时无需对正它的方向。
11067-62g11c9bgxn.png?x-oss-process=style/load
右边的这个二维码,你还可以看到一个小回字形方块,当版本大于2时,需要这个块进行再次定位。所以,生成二维码的第一步,是准备一个二维码框架。

25083-lc2rawkqlbf.png?x-oss-process=style/load
这个三个定位块的最外一个块相连起来,你会看到这样的规律。没错,就是一黑一白,再一黑,再一白。这样定位后,我们就可以根据每一个块来建立一个网格,方便识别和校准。

06489-fex54odxfgv.png?x-oss-process=style/load
建立完网格后,我们可以向其中写入数据了,但先别急。为了保证二维码符合规范,我们需要先写入一些规定的格式数据——功能性数据。这些数据可以用来识别二维码的版本、模式等。

18909-zs7dv91qxx.png?x-oss-process=style/load
截止现在制作,二维码一共发布了40个版本,分别是数字1-40。从版本1的21x21,到版本40的177x177。每个数字版本每边增加4个块,也可理解为,版本越高,能容纳的信息也越多。比如版本1纠错级别为L的二维码,能够存储17字节的数据(0.016KiB)。版本40纠错等级L的二维码,能够存储2953字节数据(2.88KiB)。

为了你的二维码能刚好够用,在生成二维码时计算机会按照需写入的数据自动计算刚好满足需求的版本。

05130-bjzis8ti9zs.png?x-oss-process=style/load
关于纠错等级,二维码中分为了L(Low)[还原约7%]、M(Medium)[还原约15%]、Q(Quartile)[还原约25%]、H(High)[还原约30%]。纠错等级越高,能存储的信息越少,但能够纠正损坏的部分也越多。

96447-udlotrwz2je.png?x-oss-process=style/load
比如即使是这个已经破损的二维码,你仍然可以扫描出它包含的数据。

78292-6a0dxpn9ki.png?x-oss-process=style/load
接下来就是数据编码模式了,二维码是一家日本公司(Denso Wave)发明的,所以除了数字、字符、字节编码外。还可以使用日文编码存储日文(汉字)信息,这种编码方式可以用更少的字节存储更多日文信息,提高利用率。

90957-seam9cxdy6.png?x-oss-process=style/load

80621-d8nlwnc0xok.png?x-oss-process=style/load
将你想写入的数据按照索引转为二进制后,补充计数指示符,即你自己想写入的数据数量,并补齐八位,按需添加补齐码后,写入的数据就剩下最后一步了——允许它纠错。

16095-sx7mbingdsr.png?x-oss-process=style/load
在二维码中,使用Reed-Solomon进行纠错处理。这种纠错方式也可见于CD、DVD中。这种纠错生成的方法非常复杂,作为仅高一的我来说能力有限,很遗憾没办法给大家讲解了,如果你了解这种算法,欢迎你评论科普!

56137-uvbrehocyzs.png?x-oss-process=style/load
接下来,从右下角开始,纵向从下往上,横向从右往左,依次写入数据。到顶或底部后反向写入,如果遇到被保留的块,直接偏移或跳过,直到所有位置被填满。

31277-nn0hr1ku26.png?x-oss-process=style/load
这样,我们就得到了一个二维码,但还是不能急,最后一步我们需要对它进行掩码操作。可以使用的掩码有八种,使用这些掩码可以使数据填充的部分尽量不会出现类似定位块的图案,提高识别率。

最终,完成所有上述操作后,你就得到了你的二维码。识别过程即反推取得原数据的过程,步骤也很类似。