QR code 二维码基础入门教程
Introduction
History and Information
- QR code 于 1994 年,由 日本公司 Denso-Wave 发明。其标准为ISO/IEC 18004:2006
- QR code 最小为 21*21,最大为177*177,其大小被称为“Version”
- Version=1, 21*21
- Version=2, 25*25
- Version=3, 29*29
- ……………
- Version=40, 177*177
- 计算公式:(V-1)*4+21。其中V为版本号
- QR code 有4种纠错等级,可恢复的码字比例为
Error Correction Level |
Error Correction Capability |
L |
恢复7%的数据 |
M |
恢复15%的数据 |
Q |
恢复25%的数据 |
H |
恢复30%的数据 |
- 数据模式包括:数字模式,数字字母模式,8字节模式,日本汉字模式,扩充解释模式(ECI),结构链接模式,FNC1模式 (实际上不同的标准支持的模式类型不同,我们不妨从简单的开始,重点关注前4种模式)
General Overview of Creating a QR Code
- 数据分析。对需要编码的数据进行分析,然后选择最佳的模式
- 数据编码。根据步骤1的模式,对数据进行编码
- 纠错编码。生成纠错码
- 构造最终消息。填充数据码和纠错码填入矩阵
- 在矩形中放置模块。将寻像图形、分隔符等一起放入矩阵
- 掩摸。用8中掩摸对编码区域图形做XOR,评价8种结果,选择最优的一种
- 格式和版本信息。生成版本信息和格式信息
接下来,我们对每个步骤进行说明
数据分析
- 数据编码将输入数据编码为一串0/1比特流,选择合适的数据模式,能够这串流尽量的短
- 各个模式可编码的字符
- 数字模式:数字0-9
- 数字字母模式:数字0-9,所有大写字母,符号 $ % * + - . / : 还有空格。具体请看数字字母模式译码表
- 8字节模式:默认情况下,可编码 ISO-8859-1 所有字符
- 日本汉字模式(Kanji,或者叫双字节模式):编码Shift JIS。也可以编码UTF-8,但是需要的字节可能更多。
- 扩充解释模式:可指定缺省字符集(这里我们不讨论这种模式)
- 结构链接模式:可以将一个数据编码为多个QR code(最多16个,这里我们不讨论这种模式)
- FNC1模式:允许QR code像GS1 code一样(这里我们不讨论这种模式)
- 如何选择合适的模式
- 输入数据都是数字,选择数字模式
- 当数字模式不满足且输入数据都在数字字母模式译码表时,选择数字字母模式(注意:数字字母模式只能编码大写字母)
- 输入数据不在数字字母模式译码表,但都在ISO-8859-1是,选择8字节模式
- 如何选择合适的模式Plus,摘自QR Code二维码–一种新型的矩阵符号 27页
下列导则可以形成对给定的输入数据决定最短位流的算法的基础。在方括号中的字符数如[5,7,9]分别用于版本1~9,版本10~26和版本27~40.在导则中,术语“专有子集”是指一种模式的字符集中的一组字符,不能与另一种更有限的字符集共享,例如,8位字节字符集的专有子集由JIS
8的值00HEX~FFHEX组成,但它不包括十六进制的值
20,24,25,2A,2B,2D~3D和41~5A;因为它们是字符字符集的一组字符{A~Z,space,$,%,*,+,-,’, /,:}
- 混合多种模式(这里不讨论这种模式)
- 选择好了合适的模式,接下来是数据编码
数据编码
Step 1 选择纠错等级
Error Correction Level |
Error Correction Capability |
L |
恢复7%的数据 |
M |
恢复15%的数据 |
Q |
恢复25%的数据 |
H |
恢复30%的数据 |
- 纠错等级越高,纠错码就越多,那么可编码的数据就变少,因此QR code的版本可能要更大
Step 2 确定数据的最小版本
编码模式 |
最大可编码字符数(纠错等级L,版本40) |
数字模式 |
7089 |
字母数字模式 |
4296 |
8字节模式 |
2953 |
日本汉字模式 |
1817 |
Step 3 添加模式指示符
- 比特流最前面是模式指示符,模式指示符是一个4比特的指示符,指示符如下
编码模式 |
模式指示符 |
数字模式 |
0001 |
数字字母模式 |
0010 |
8字节模式 |
0100 |
日本汉字模式 |
1000 |
ECI模式 |
0111 |
- 国标的指示符长这样:
Step 4 添加字符计数指示符
- 将输入数据的字符数 编码为一串指示符。不同版本字符数字指示符的长度不一样。
- 举个例子:HELLO WORLD,版本1,模式=字母数字模式,字符数=11,那么字符计数指示符的长度为9个比特。11的二进制:1011,不满9位则左边填充0,得到 000001011。结合上一步的模式指示符,当前编码比特流为:0010 0000001011
Step 5 利用模式对输入数据编码
- 不同模式的编码方式不同,通过具体例子我们来不同模式的熟悉编码过程
数字模式编码
- 将输入数据分为3位一组。8675309 -> {867, 530, 9}
- 将每组数据转为二进制,如果一组数据是3个,那么转换为10位二进制,如果是2位,转换为7位,如果是1位,转换为4位
- 867 -> 1101100011
- 530 -> 1000010010
- 9 -> 1001
字母数字模式编码
- 将输入数据分为2个一组。HELLO WORLD -> {HE, LL, O , WO, RL, D}
- 通过查表 字母数字模式的编码/译码表,将数据转为对应的值。{{17,14}, {21,21}, {24,36},{32,24},{27,21},{13}}
- 每组的第一个数乘上45,然后加上第二个数。{17,14} -> 17*45+14=779。
- 将3得到的结果转为11位二进制。779 -> 01100001011
- 如果只有一个字符,,转换为6位二进制。{D} -> {13} -> 001101
- 重复3-5步,得到结果 01100001011 01111000110 10001011100 10110111000 10011010100 001101
8字节模式
- 默认字符集为ISO 8859-1。如果输入字符不在ISO 8859-1中,可转换为UTF-8。
- 通过查表,将输入数据转为16进制。例如,”Hello, world!”
- H → 0x48
- e → 0x65
- l → 0x6c
- l → 0x6c
- o → 0x6f
- , → 0x2c
- → 0x20
- w → 0x77
- o → 0x6f
- r → 0x72
- l → 0x6c
- d → 0x64
- ! → 0x21
- 将十六进制转为二进制
- H → 0x48 → 01001000
- e → 0x65 → 01100101
- l → 0x6c → 01101100
- l → 0x6c → 01101100
- o → 0x6f → 01101111
- , → 0x2c → 00101100
- → 0x20 → 00100000
- w → 0x77 → 01110111
- o → 0x6f → 01101111
- r → 0x72 → 01110010
- l → 0x6c → 01101100
- d → 0x64 → 01100100
- ! → 0x21 → 00100001
日本汉字模式
编码结果
模式指示符 |
字符计数指示符 |
编码序列 |
0010 |
000001011 |
01100001011 01111000110 10001011100 10110111000 10011010100 001101 |
Step 6 填充空余的比特位
- 通过查表error correction table得到最大数据比特位数。例如,1-Q共有13个码字,每个码字有8位,因此最大数据比特位数:13*8=104
- 添加终止符。终止符位4比特长度:0000。但是如果编码序列为102,只剩下2位,那么只需要填充2位的0。添加了终止符后的编码序列为
模式指示符 |
字符计数指示符 |
编码序列 |
终止符 |
0010 |
000001011 |
01100001011 01111000110 10001011100 10110111000 10011010100 001101 |
0000 |
如果当前编码序列的最后一个码字不满8位,那么填充0至8位
当前数据:00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 010000
填充后的数据:00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 010000 00
如果当前数据太短了,没有填满最大比特位数,那么重复填充 11101100 00010001
最终数据: 00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 010000 00 11101100 00010001 11101100
最后,用一张图来总结以上过程