二维码系列 -- 二维码原理(二)

991 阅读6分钟

二维码原理

本文简单的介绍二维码的组成, 旨在了解组成及原理, 复杂的编码过程可能会使文章难以理解故不做讨论.

概述

  • 一共有40种, 官方叫版本Version (Version1 ~ Version40)。

  • Version 1是21 x 21的矩阵,Version 2是 25 x 25的矩阵,每增加一个version,就会增加4的尺寸,公式是:(V - 1) * 4 + 21(V是版本号)

  • 最高Version 40,(40 - 1) * 4 + 21 = 177,所以最高是177 x 177

image.png

定位图案

Position Detection Pattern

  • Position Detection Pattern(3处)是定位图案,标记二维码的大小。

  • 这三个定位图案有白边叫Separators for Postion Detection Patterns。

  • 之所以三个而不是四个意思就是三个就可以标识一个矩形了。

image.png

Alignment Patterns

  • Alignment Patterns(多个) 只有Version 2以上(包括Version2)的二维码需要这个东东,同样是为了定位用的。

image.png

  • Alignment的位置可以根据QR Code关于Table-E.1的定义表:

image.png

例如Version8,它的校正图形(Alignment Patterns)的数量在表格中为6个,位置分别为(6, 24, 42),画在图中为:
image.png

Timing Patterns

  • Timing Patterns(2条线)也是用于定位的。

  • 原因是二维码有40种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。

  • 都是同样的位置, 直接链接就可以了

功能性数据

Format Information

  • Format Information(3处) 存在于所有的尺寸中, 占用15个bits,用于存放一些格式化数据的。

image.png

其中5个数据bits: 2个bits用于表示Error Correction Level (参考下面: 纠错维度表), 3个bits表示使用什么样的Mask (表示编码方式, 在后面会讲到) 另外的10个纠错bits: 通过BCH Code来计算

纠错维度

Error Correction Level
L水平7%的字码可被修正01
M水平15%的字码可被修正00
Q水平25%的字码可被修正11
H水平30%的字码可被修正10

Version Information

  • Version Information(2处) 在 >= Version 7以上,需要预留两块3 x 6的区域存放一些版本信息。

image.png

总共18个bits,其中6个bits为版本号、12bits为纠错码,例如Version7:
image.png

数据码和纠错码

  • 除了上述的那些地方,剩下的地方存放 Data Code 数据码 和 Error Correction Code 纠错码。

  • 举个简单具体例子来说明是如何进行数据编码的:

基础数据编码

我们用"HELLO WORLD"的字符串进行编码: 我们从字符索引表中找到这几个字母的索引: image.png

根据表格我们可以得到 [17, 14, 21, 21, 24, 36, 32, 24, 27, 21, 13], 然后两两分组[(17, 14), (21, 21), (24, 36), (32, 24), (27, 21), (13)]

把每一组转成11bits的二进制, 如(17, 14)就是17 * 45 + 14 = 779, 最终得到 01100001011 全部转换后: 01100001011 01111000110 10001011100 10110111000 10011010100 001101

把字符的个数11, 转成二进制: 000001011(Version 1-H为9 bits)

编码类型为 字符编码(Alphanumeric Mode): 0010

Mode NameMode Indicator
Numeric Mode0001
Alphanumeric Mode0010
Byte Mode0100
Kanji Mode1000
ECI Mode0111
编码字符数HELLO WORLD的编码结束
001000000101101100001011 01111000110 10001011100 10110111000 10011010100 0011010000

按8bits重排, 如果所有的编码加起来不是8个倍数, 需要在结尾补零

00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000

如果最后还没有达到我们的最大bits数的限制,还要加上一些补齐码(魔数11101100 00010001 )

我们用Version 1的Q纠错级进行演示,其最大需要104个bits,而我们上面只有80个bits, 还需要补24个bits,也就是需要3个Padding Bytes

00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000 11101100 00010001 11101100

根据纠错级别加入纠错码

由于逻辑比较复杂, 这里不做详细说明, 感兴趣的可以参考官方文档

填入最终编码

  • 最终编码的填充方式如下, 从右下角开始沿着红线填我们的各个bits,1是黑色,0是白色。

  • 如果遇到了上面的非数据区,则绕开或跳过

image.png

  • 这样下来,我们的图就填好了, 但是有时候可能会出现大面积的空白或黑块, 这就造成扫描识别困难 我们还要做Masking操作,

Masking操作

  • 和上面生成的图做XOR操作, 该操作只能应用在数据码和纠错码放置的区域 image.png

  • 其Mask的标识码如下所示:(其中的i,j分别对应于上图的x,y)
    image.png

  • 下面是Mask后的一些样子,我们可以看到被某些Mask XOR了的数据变得比较零散了。
    image.png

其他扩展

二维码加 LOGO

  • 我们经常会看到二维码 中间会有一个公司或者产品的 logo

  • 二维码是根据规范画出来的有一定规则的小方块, 如果要在中间加一个 logo 那肯定不符合二维码的规范

  • 那我们见到 logo 是怎么加上去的呢?

    • 其实很简单, 就是在原来的二维码覆盖一个 logo
    • 那么问题又来了, 这样的话挡住了二维码, 那还能扫描成功吗?
    • 没有问题的, 你没有看错. 主要是因为二维码有纠错特性
    • 创建二维码时应用的错误纠正程度(可参考 纠错维度):L(7%)、M(15%)、H(25%)、V(30%)

参考文档

维基百科-二维码
QR code
深度探索二维码原理及其应用
二维码的生成细节和原理