二维码原理
本文简单的介绍二维码的组成, 旨在了解组成及原理, 复杂的编码过程可能会使文章难以理解故不做讨论.
概述
-
一共有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
定位图案
Position Detection Pattern
-
Position Detection Pattern(3处)是定位图案,标记二维码的大小。
-
这三个定位图案有白边叫Separators for Postion Detection Patterns。
-
之所以三个而不是四个意思就是三个就可以标识一个矩形了。
Alignment Patterns
- Alignment Patterns(多个) 只有Version 2以上(包括Version2)的二维码需要这个东东,同样是为了定位用的。
- Alignment的位置可以根据QR Code关于Table-E.1的定义表:
例如Version8,它的校正图形(Alignment Patterns)的数量在表格中为6个,位置分别为(6, 24, 42),画在图中为:
Timing Patterns
-
Timing Patterns(2条线)也是用于定位的。
-
原因是二维码有40种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。
-
都是同样的位置, 直接链接就可以了
功能性数据
Format Information
- Format Information(3处) 存在于所有的尺寸中, 占用15个bits,用于存放一些格式化数据的。
其中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的区域存放一些版本信息。
总共18个bits,其中6个bits为版本号、12bits为纠错码,例如Version7:
数据码和纠错码
-
除了上述的那些地方,剩下的地方存放 Data Code 数据码 和 Error Correction Code 纠错码。
-
举个简单具体例子来说明是如何进行数据编码的:
基础数据编码
我们用"HELLO WORLD"的字符串进行编码: 我们从字符索引表中找到这几个字母的索引:
根据表格我们可以得到 [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 Name | Mode Indicator |
---|---|
Numeric Mode | 0001 |
Alphanumeric Mode | 0010 |
Byte Mode | 0100 |
Kanji Mode | 1000 |
ECI Mode | 0111 |
编码 | 字符数 | HELLO WORLD的编码 | 结束 |
---|---|---|---|
0010 | 000001011 | 01100001011 01111000110 10001011100 10110111000 10011010100 001101 | 0000 |
按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是白色。
-
如果遇到了上面的非数据区,则绕开或跳过
- 这样下来,我们的图就填好了, 但是有时候可能会出现大面积的空白或黑块, 这就造成扫描识别困难 我们还要做Masking操作,
Masking操作
-
和上面生成的图做XOR操作, 该操作只能应用在数据码和纠错码放置的区域
-
其Mask的标识码如下所示:(其中的i,j分别对应于上图的x,y)
-
下面是Mask后的一些样子,我们可以看到被某些Mask XOR了的数据变得比较零散了。
其他扩展
二维码加 LOGO
-
我们经常会看到二维码 中间会有一个公司或者产品的 logo
-
二维码是根据规范画出来的有一定规则的小方块, 如果要在中间加一个 logo 那肯定不符合二维码的规范
-
那我们见到 logo 是怎么加上去的呢?
- 其实很简单, 就是在原来的二维码覆盖一个 logo
- 那么问题又来了, 这样的话挡住了二维码, 那还能扫描成功吗?
- 没有问题的, 你没有看错. 主要是因为二维码有纠错特性
- 创建二维码时应用的错误纠正程度(可参考 纠错维度):L(7%)、M(15%)、H(25%)、V(30%)