QR code 二维码基础入门教程

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. 数据分析。对需要编码的数据进行分析,然后选择最佳的模式
  2. 数据编码。根据步骤1的模式,对数据进行编码
  3. 纠错编码。生成纠错码
  4. 构造最终消息。填充数据码和纠错码填入矩阵
  5. 在矩形中放置模块。将寻像图形、分隔符等一起放入矩阵
  6. 掩摸。用8中掩摸对编码区域图形做XOR,评价8种结果,选择最优的一种
  7. 格式和版本信息。生成版本信息和格式信息
    接下来,我们对每个步骤进行说明

数据分析

  • 数据编码将输入数据编码为一串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的值 00 H E X ~ F F H E X 组成,但它不包括十六进制的值
20,24,25,2A,2B,2D~3D和41~5A;因为它们是字符字符集的一组字符{A~Z,space,$,%,*,+,-,’, /,:}

P80719-102344_编辑_编辑.jpg-242.5kB

  • 混合多种模式(这里不讨论这种模式)
  • 选择好了合适的模式,接下来是数据编码

数据编码

Step 1 选择纠错等级

Error Correction Level Error Correction Capability
L 恢复7%的数据
M 恢复15%的数据
Q 恢复25%的数据
H 恢复30%的数据
  • 纠错等级越高,纠错码就越多,那么可编码的数据就变少,因此QR code的版本可能要更大

Step 2 确定数据的最小版本

  • QR code的数据容量由模式纠错等级决定,详勘Character Capacities by Version, Mode, and Error Correction
  • 如何确定数据的最小版本:
    1. 确定模式和纠错等级
    2. 根据输入数据的字符个数,查表得到结果
    3. 举个例子,输入数据:HELLO WORLD,模式:数字字母模式,纠错等级:Q,字符个数:11,查表得到版本1为最小版本(版本1Q在数字字母模式最多可编码16个字符)。同理,输入数据改为:HELLO THERE WORLD,查表得到版本2为最小版本
  • 容量上限。版本40,纠错等级L时,容量最大,可容纳的字符数如下表
编码模式 最大可编码字符数(纠错等级L,版本40)
数字模式 7089
字母数字模式 4296
8字节模式 2953
日本汉字模式 1817

Step 3 添加模式指示符

  • 比特流最前面是模式指示符,模式指示符是一个4比特的指示符,指示符如下
编码模式 模式指示符
数字模式 0001
数字字母模式 0010
8字节模式 0100
日本汉字模式 1000
ECI模式 0111
  • 国标的指示符长这样:image_1cio78g2fs0n1fe752og6121cq.png-45.7kB

Step 4 添加字符计数指示符

  • 将输入数据的字符数 编码为一串指示符。不同版本字符数字指示符的长度不一样。QQ图片20180719105523.png-21.2kB
  • 举个例子:HELLO WORLD,版本1,模式=字母数字模式,字符数=11,那么字符计数指示符的长度为9个比特。11的二进制:1011,不满9位则左边填充0,得到 000001011。结合上一步的模式指示符,当前编码比特流为:0010 0000001011

Step 5 利用模式对输入数据编码

  • 不同模式的编码方式不同,通过具体例子我们来不同模式的熟悉编码过程

数字模式编码

  1. 将输入数据分为3位一组。8675309 -> {867, 530, 9}
  2. 将每组数据转为二进制,如果一组数据是3个,那么转换为10位二进制,如果是2位,转换为7位,如果是1位,转换为4位
    • 867 -> 1101100011
    • 530 -> 1000010010
    • 9 -> 1001

字母数字模式编码

  1. 将输入数据分为2个一组。HELLO WORLD -> {HE, LL, O , WO, RL, D}
  2. 通过查表 字母数字模式的编码/译码表,将数据转为对应的值。{{17,14}, {21,21}, {24,36},{32,24},{27,21},{13}}
  3. 每组的第一个数乘上45,然后加上第二个数。{17,14} -> 17*45+14=779。
  4. 将3得到的结果转为11位二进制。779 -> 01100001011
  5. 如果只有一个字符,,转换为6位二进制。{D} -> {13} -> 001101
  6. 重复3-5步,得到结果 01100001011 01111000110 10001011100 10110111000 10011010100 001101

8字节模式

  1. 默认字符集为ISO 8859-1。如果输入字符不在ISO 8859-1中,可转换为UTF-8。
  2. 通过查表,将输入数据转为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
  3. 将十六进制转为二进制
    • 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

最后,用一张图来总结以上过程
QR Code编码流程图.png-45kB