目录
文章部分来源于CSDN博主「琦小虾」的原创文章,原文链接:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/78837864
一、二维码
(一)二维码的基本知识
1、二维条码的码制
-
堆叠式/行排式二维条码(堆积式或层排式二维码)
编码原理:建立在一维条码基础之上,按需要堆积成二行或多行
由于行数的增加,需要对行进行判定,其译码算法与软件也不完全相同于一维条码
有代表性的行排式二维条码有:Code 16K、Code 49、PDF417等。
- 矩阵式二维码(棋盘式二维码)
编码原理:在一个矩形空间通过黑、白像素在矩阵中的不同分布进行编码。在矩阵相应元素位置上,用点(方点、圆点或其他形状)的出现表示二进制“1”,点的不出现表示二进制的“0”
矩阵式二维条码是建立在计算机图像处理技术、组合编码原理等基础上的一种新型图形符号自动识读处理码制
具有代表性的矩阵式二维条码有:Code One、Maxi Code、QR Code、 Data Matrix等。
2、二维条码/二维码的特点
高密度编码,信息容量大:比普通条码信息容量约高几十倍
编码范围广
该条码可以把图片、声音、文字、签字、指纹等可以数字化的信息进行编码,用条码表示出来
可以表示多种语言文字
在小空间内打印:QR码使用纵向和横向两个方向处理数据,如果是相同的信息量,QR码所占空间为条形码的十分之一左右
容错能力强,具有纠错功能:这使得二维条码因穿孔、污损等引起局部损坏时,照样可以恢复数据并正确得到识读,数据恢复以码字为单位(是组成内部数据的单位,在QR码的情况下,每8比特代表1码字)
可以从任意方向读取:QR码中的3处定位图案,可以帮助QR码不受背景样式的影响,实现快速稳定的读取
(二)QR码基本结构
1、定位图案与校正图案
-
定位图案与尺寸大小无关,一定是一个 7×7 的矩阵
-
校正图案与尺寸大小无关,一定是一个 5×5 的矩阵
-
校正图案绘制的位置,可参看 QR Code Spec 的 Table-E.1 一表查询,部分内容如下图
-
比如:对于 Version 8 的二维码,行列值在 6, 24, 42 的几个点都会有校正图案
2、时序图案
-
是两条连接三个定位图案的线,QR码中黑白相间的点线,用于确定QR码的宽度以及点数
3、格式信息
存储在定位标志附近的两条点带中,格式信息存储了两次,因此即使QR码被部分遮挡也可以读取
纠错的目的:即使部分信息丢失也仍然可以读取
格式信息保存了三种关键信息:掩码类型、纠错等级、纠错格式
-
纠错等级
表示QR码中存储了多少冗余信息
纠错等级越高,就意味着冗余等级越高,因此QR码遭到破坏时仍然能被读取的可能性就越高
纠错等级 | |
L等级(Low) | 7%的字码可被修正 |
M等级(Medium) | 15%的字码可被修正 |
Q等级(Quartile) | 25%的字码可被修正 |
H等级(High) | 30%的字码可被修正 |
-
掩码
- QR码在白色区域和黑色区域数量相同时读取的效果最好,如果数据区域出现连续的空白或者连续的黑色区,就需要用到掩码
QR码提供八种掩码模型,这些掩码会被逐个尝试,直到找到效果最好的掩码
掩码的信息会存储下来,供读取装置解除掩码使用,最终得到实际数据
这个数据是从右下角开始的,按照如下图所示的方向返回。当然,因为QR码可以从任何角度读取,因此实际上从哪里开始读取都没关系
QR码中的第一块信息是数据编码的模式,而第二块信息是数据的长度
在这个例子中,每个字符包含8个比特(也就是一个字节),一共有24个字节
- 未使用空间被用来存储纠错信息,如下图中紫色空间所示,目的是在QR码遭到损坏时依然能够读取
4、版本信息
-
Version 7 及其以上的二维码,需要加入版本信息
-
版本信息依附在定位图案周围,故大小固定为 18bits。水平竖直方向的填充方式如下图
-
18bits 的版本信息中,前 6bits 为版本号 (Version Number),后 12bits 为纠错码 (BCH Bits)
-
假设存在一个 Version 为 7 的二维码(对应 6bits 版本号为 000111),其纠错码为 110010010100;则版本信息图案中的应填充的数据为:000111110010010100
(三)QR码的版本与码元计算
二维码一共有40个版本version,每个版本都具备固有的码元结构(码元数)
码元结构:二维码中的码元数,码元是指构成QR码的方形黑白点
版本1(21码元×21码元)开始,在纵向和横向各自以4码元为单位递增,一直到版本40(177码元×177码元)
计算公式:(V-1)*4 + 21(V是版本号)
二、数据编码
(一)数据编码信息
-
二维码支持的数据编码模式,中文编码模式位1101
-
不同版本(即不同尺寸)的二维码,单个编码对应二进制的位数
(二)数据编码形式
1、数字编码
数字编码范围: 0~9
运算原理
统计需要编码数字的个数是否为 3 的倍数:如果不是 3 的倍数,则剩下的 1 位或 2 位会被转为 4bits 或 7bits(十进制转二进制)
每三位数字都会被编成10bits
-
实例:对于 Version 1 尺寸的二维码,纠错级别为 H,编码为:01234567
解析步骤
将上述数字分为三组:012, 345, 67
查询图 2.2 表格内容,Version 1 二维码的数字编码应转换为 10bits 的二进制数字,故将三组数字转为二进制分别为:012→0000001100, 345→0101011001, 67→1000011
将三个二进制串连接起来:0000001100 0101011001 1000011
将数字的个数转成二进制:查询表 2.2 内容,Version 1 二维码的数字个数应转换为 10bits 的二进制数字,数字共有 8 个,故数字个数的二进制形式为:8→0000001000
查询图 2.1 表格内容,数字编码的标志为 0001,将编码标志与步骤 4 编码结果加到步骤 3 结果之前,故最终结果为:0001 0000001000 0000001100 0101011001 1000011
-
总结:数字编码的标志0001 + 数字长度的二进制表示 + 数字内容的二进制表示
2、字符编码
字符编码范围: 0~9,大写 A~Z(无小写),几个符号($ % * + - . / 和空格)
运算原理
Char 表示字符,Value 表示字符对应的索引值,索引表中共 45 种对应关系
字符编码的过程就是将每两个字符分为一组,然后转成 45 进制,再转为 11bits 的二进制结果。对于落单的一个字符,则转为 6bits 的二进制结果
-
实例:对于 Version 1 尺寸的二维码,纠错级别为 H,编码为:AE-86
解析步骤
在表 2.3 的字符索引表中分别找到 AE-86 五个字符的索引分别为:(10, 14, 41, 8, 6)
将五个字符两两分组:(10, 14) (41, 8) (6)
字符编码应将字符组转换为 11bits 的二进制,故上述三组字符首先转为 45 进制后再转为二进制
(10, 14):转为 45 进制:10×45+14=464;再转为 11bits 的二进制:00111010000;
(41, 8):转为 45 进制:41×45+8=1853;再转为 11bits 的二进制:11100111101;
(6):转为 45 进制:6;再转为 6bits 的二进制:000110
4. 将步骤 3 中得到的三个二进制结果连接起来:00111010000 11100111101 000110
5. 查询表 2.2 内容,Version 1 二维码的字符个数应转换为 9bits 的二进制数字,对于 5 个字符,二维码字符个数转为 9bits 二进制为:000000101
6. 查询表 2.1 内容,字符编码的标志为 0010,将编码标志与步骤 5 编码结果加到步骤 4 结果之前,故最终编码结果为:0010 000000101 00111010000 11100111101 000110
-
总结:字符编码的标志0010 + 字符长度的二进制表示 + 字符内容的二进制表示
三、结束符与补齐符
-
问题:对于 Version 1 尺寸的二维码,纠错级别为 H,以笔者的英文名CHANDLERGENG
-
按照字符编码进行分析,得到编码如下
编码 | 字符数 | CHANDLERGENG 的编码 |
0010 | 000001101 | 01000101101 00111011001 01001011110 01010010001 01011011110 10000011011 |
(一)结束符
-
结束符:0000
-
如果所有的编码加起来不是 8 的倍数,则还需要在后面加上足够的 0。如上面一共有 83bits,所以与 8 的倍数还相差两位,故在最后加上 5 个 0
-
上表最终的数据变为:00100000 01101010 00101101 00111011 00101001 01111001 01001000 10101101 11101000 00110110 00000000(红色为结束符,后面五个0为补齐的)
(二)补齐符
-
如果最后还没有达到我们最大的 Bits 数限制,则需要在编码最后加上补齐符(Padding Bytes)
-
补齐符内容是不停重复两个字节:11101100 和 00010001
-
这两个二进制转成十进制,分别为 236 与17
-
关于每一个Version的每一种纠错级别的最大Bits限制
-
表 3.1 中提到的 codewords(码字),一个码字是一个字节。对于 Version 1 的 H 纠错级别,共需要 26 个码字,即 208bits
-
现在加上用 0 补全的结束符,已经有了 88bits,故还需要补上 120 bits
-
补齐后的编码(数据码)为:00100000 01101010 00101101 00111011 00101001 01111001 01001000 10101101 11101000 00110110 00000000 11101100 00010001
四、纠错码
-
二维码对数据码加上纠错码的过程,首先要对数据码进行分组,即分成不同的块(Block)
对于表中的最后两列的内容
纠错块个数(Number of error correction blocks):需要划分纠错快的个数
纠错块码字数(Error Correction Code Per Blocks):每个块中的码字个数,即有多少个字节Bytes
表中最下面关于 (c,k,r) 的解释
c:码字总个数
k:数据码个数
r:纠错码容量
c,k,r的关系公式:c=k+2×rc=k+2×r
-
以上图 4.1 中的 Version 5 + H 纠错机为例:图中红色方框说明共需要 4 个块(上下行各一组,每组 2 个块)
第一组的属性:
纠错块个数 = 2:该组中有两个块
(c, k, r) = (33, 11, 11):该组中每个块共有 33 个码字,其中 11 个数据码, 11×2=22 个纠错码
第二组的属性
纠错块个数 = 2:该组中有两个块
(c, k, r) = (34, 12, 11):该组中每个块共有 34 个码字,其中 12 个数据码, 11×2=22 个纠错码
-
具体示例如下表所示,且由于使用二进制会使得表格过大,故转为范围在 0~255 的十进制。其中组 1 的每个块,都有 11 个数据码, 22 个纠错码;组 2 的每个块,都有 12 个数据码,22 个纠错码
五、最终编码
-
此时得到了数据,但还不能开始画图,因为二维码还需要将数据码与纠错码的各个字节交替放置
(一)穿插位置
1、数据码穿插位置
-
数据码表示
快数 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 67 | 85 | 70 | 134 | 87 | 38 | 85 | 194 | 119 | 50 | 6 | |
2 | 66 | 7 | 118 | 134 | 242 | 7 | 38 | 86 | 22 | 198 | 199 | |
3 | 247 | 119 | 50 | 7 | 118 | 134 | 87 | 38 | 82 | 6 | 134 | 151 |
4 | 194 | 6 | 151 | 50 | 16 | 236 | 17 | 236 | 17 | 236 | 17 | 236 |
-
提取每一列数据
第一列:67, 66, 247, 194;
第二列:85, 7, 119, 6;
……
第十一列:6, 199, 134, 17;
第十二列:151, 236;
-
将上述十二列的数据拼在一起:67, 66, 247, 194, 85, 7, 119, 6,…, 6, 199, 134, 17, 151, 236
2、纠错码表示与数据码一样,再此就不赘述了
-
以上为二维码的数据区
(二)剩余位
-
对于某些 Version 的二维码,得到上面的数据区结果长度依旧不足,需要加上最后的剩余位。比如对于 Version 5 + H 纠错等级的二维码,剩余位需要加 7bits,即加 7 个 0。参看 QR Code Spec 的 Table-1 一表即可查询不同 Version 的剩余位信息,如下图 5.1 所示:
版权声明:本文为CSDN博主「琦小虾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/78837864