「QRCode 标准阅读」#1 构成及数据编码
基础描述及结构(6.1、6.3)
基础描述(5.3、6.1)
- 块位置:左上角为原点 (0, 0) 向下x+,向右y+
- 版本表示:Version V-E(其中V是版本号,E是纠错等级)
- 数据表示:黑块-1 白块-0(可以带背景全部反色)
- 大小:从版本1到版本40依次是 21x21 ~ 177x177(每增加一个版本,边长增加4)
- 支持的最多字符数(版本40)
- 数字模式:7089
- 字母模式:4296
- 字节模式:2953
- 日文模式:1817
- 纠错等级允许的恢复比例
- L:7%
- M:15%
- Q:25%
- H:30%
二维码结构(6.3)
- 功能图案(function patterns)
- 特征符(finder pattern)7x7黑圈 5x5白圈 3x3黑块
- 分割线(separator)在特征符周围的一圈全白区域
- 时序图案(timing patterns)第7行第7列的两条黑白条纹
- 对齐图案(alignment patterns)版本1无,版本2-6 1个,版本7-13 6个……(附录E)
- 静默区(quiet zone)至少4个单位宽
- 编码区域(encoding region)
- 格式信息(format information)左上角分割线外一圈,左下角分割线右侧,右上角分割线下侧
- 版本信息(version information)版本7后才有,在左下分割线上侧,右上分割线左侧
- 数据及纠错码区域
数据编码(7.4)
数据序列(7.4.1)
默认的 ECI 模式下,比特流以模式标识符开始。如果不是默认 ECI 模式,则需要从 ECI 头开始:
- (4 bits)ECI 模式标识符
- (8/16/24 bits)ECI Designator
比特流的剩余部分由下面几部分组成:
- (4 bits)模式标识符
- 字符数量标识符(长度见下第二个表)
- 数据比特流
模式 | 标识符 | 说明 |
---|---|---|
ECI | 0111 | |
数字模式 | 0001 | 只包含数字0-9,3个数字 10 bits |
字母数字模式 | 0010 | 45个字符,0-9A-Z 及9个符号 空格$%*+-./:,2个字符 11 bits |
字节模式 | 0100 | 每个字符 8 bits |
日本汉字模式 | 1000 | |
结构添加模式 | 0011 |
版本 | 数字模式字符数量标识符长度 | 字母模式…… | 字节模式…… | 日文模式…… |
---|---|---|---|---|
1~9 | 10 | 9 | 8 | 8 |
10~26 | 12 | 11 | 16 | 10 |
27~40 | 14 | 13 | 16 | 12 |
ECI 模式(7.4.2)
ECI 模式即使用某些特定的字符映射来把字符转换为比特流
而且都使用字节模式来表示数据(即在 ECI 头后的模式标识符为字节模式的 0100)
每个 ECI 都有一个六位数编号(assignment value),可能占 1、2、3 个 codewords,具体标识方式见下表(占1个 codewords 时开头一定是0,占2个时开头一定是10,占3个时开头一定是110)表中 xxxxxxxx 表示编号的二进制
ECI Assignment Value | Codewords values |
---|---|
000000 ~ 000127 | 0xxxxxxx |
000000 ~ 016383 | 10xxxxxx xxxxxxxx |
000000 ~ 999999 | 110xxxxx xxxxxxxx xxxxxxxx |
而且 ECI 模式下中途可以更换 ECI 指示器,一个 5C(01011100)表示换新的 ECI,后面要接6个 codewords 即6个数字(十六进制30~39)表示编号,而不是用上表中的表示方法。而 5C 正常情况下表示 \ ,所以表示 \ 这个原数据需要用两个 5C
- 例子 1
- 使用 ISO/IEC 8859-7(ECI 000009)来表示希腊字母ΑΒΓΔΕ(该 ECI 下表示为十六进制 A1 A2 A3 A4 A5)
- 比特流:
- ECI 标识符:
0111
- ECI 编号:
00001001
- 字节模式标识符:
0100
- 字符数量:
00000101
(5个字符) - 数据:
10100001 10100010 10100011 10100100 10100101
- ECI 标识符:
- 所以最终的比特流:
0111 00001001 0100 00000101 10100001 10100010 10100011 10100100 10100101
- 例子 2(14.3)
- 需要编码的数据:ABC\123456
- 数据流中十六进制(字节模式标识符0100后):41 42 43 5C 5C 31 32 33 34 35 36
- 需要编码的数据:ABC<后接 ECI 123456 下的数据……>
- 数据流中十六进制(字节模式标识符0100后):41 42 43 5C 31 32 33 34 35 36 ……
- 需要编码的数据:ABC\123456
数字模式(7.4.3)
输入的数字字符串(因为开头可以是0)要被分成3个一组,每组会转换为 10 bits 的二进制串(999 -> 1111100111
)。剩余不到3个的部分,如果剩2个数字,则将其转换为 7 bits 的二进制串(99 -> 1100011
)如果剩1个数字,则将其转换为 4 bits 的二进制串(9 -> 1001
)
然后开头加上数字模式标识符 0001
和数量标识符(字符个数转为二进制,并开头补0至长度,长度由版本决定,见上 7.4.1 部分的第二个表)
- 例子
- 数据内容:
01234567
(保留开头0) - 数据流部分:
- 数字模式标识符:
0001
- 数量标识符:
0000001000
(8,且版本1下规定为 10 bits) - 数据:
- 012 ->
0000001100
- 345 ->
0101011001
- 67 ->
1000011
- 012 ->
- 数字模式标识符:
- 完整数据比特流:
0001 0000001000 0000001100 0101011001 1000011
- 数据内容:
数字模式下的比特流长度为:
$$B=M+C+10\times\lfloor\frac{D}{3}\rfloor+R$$
其中 M 为 4,C 为数量标识符长度(版本1~9为 10,版本10~26为 12,版本27~40为 14),D为输入字符个数,R为剩余部分(若 D mod 3 = 0 则为 0,若 D mod 3 = 1 则为 4,若 D mod 3 = 2 则为 7)
字母数字模式(7.4.4)
数字字母模式(Alphanumeric mode)下支持的编码字符有45个,把它们从0编号至44。其中 0-9 对应数字 0-9,10-35 对应字母 A-Z,36-44 对应9个符号:
输入的字符先按照上表转换为数值,然后分为两个一组,每一组内把 第一个数值 × 45 + 第二个数值,再转换为长度为 11 bits 的二进制串(最大为 44×45+44=2024 -> 11111101000
)。如果字符长度为奇数,则会剩余出一个字符,需要将其值转换为长度为 6 bits 的二进制串(最大为 11 -> 101100
)
然后开头加上字母数字模式标识符 0010
和数量标识符(长度由 7.4.1 第二个表规定)
- 例子
- 数据内容:AC-42
- 数据流部分:
- 字母数字模式标识符:
0010
- 数量标识符:
000000101
(5,且版本1下规定长度为9) - 数据:AC-42 -> 10 12 41 4 2 -> (10 12)(41 4)(2)
- 10 12 -> 10*45+12=462 ->
00111001110
- 41 4 -> 41*45+4=1849 ->
11100111001
- 2 -> 2 ->
000010
- 10 12 -> 10*45+12=462 ->
- 字母数字模式标识符:
- 完整数据比特流:
0010 000000101 00111001110 11100111001 000010
字母数字模式下的比特流长度为:
$$B=M+C+11\times\lfloor\frac{D}{2}\rfloor+6\times(D\bmod 2)$$
其中 M 为 4,C 为数量标识符长度,D 为原数据长度
字节模式(7.4.5)
字节模式(Byte mode)下把每个字符根据 Latin-1(ISO/IEC 8859-1)编码成 8 bits(1字节),直接接在字节模式标识符 0100
和数量标识符(长度由 7.4.1 第二个表规定)的后面。
字节模式下的比特流长度:
$$B=M+C+8\times D$$
其中 M 为 4,C 为数量标识符长度,D 为原数据长度
中文编码
中文在转换成比特流的时候也使用字节模式,需要用 UTF-8 编码,每个字符会被编码成 3 个字节
混合模式(7.4.7)
一个二维码的数据流中也可以使用多种模式,且不需要特别表示。更换新的模式时只需要正常添加 模式标识符+数量标识符+数据 即可
- 例子
- 原始数据:123测试
- 数据流:
- 数字模式:
- 标识符:
0001
- 数量标识符:
0000000011
(3,长度10) - 数据:123 ->
0001111011
- 标识符:
- 字节模式:测试 -> E6 B5 8B / E8 AF 95
- 标识符:
0100
- 数量标识符:
00000110
(6,长度8) - 数据:
- 测 ->
11100110 10110101 10001011
- 试 ->
11101000 10101111 10010101
- 测 ->
- 标识符:
- 数字模式:
- 完整数据比特流:
0001 0000000011 0001111011 0100 00000110 11100110 10110101 10001011 11101000 10101111 10010101
结束符(7.4.9)
在数据的末尾要填充4个0作为结束符,如果容量不足的话可以缩短或省略
即能填下则加4个0,填不下则能加几个0就加几个0
填充 padding bits(7.4.10)
转换后的数据比特流还需要填充至二维码的数据容量
- 首先先用
0
补充比特流长度到 8 的整数倍 - 然后用
11101100
和00010001
交替填补到二维码数据容量
具体的数据容量由版本号和纠错等级决定,且数据容量(比特)一定为8的倍数,完整数据见文档的 33~36 页(整个 pdf 的第 41~44 页)
注:这个地方 QRazyBox 网站存在 bug,有时无法正常识别填充的 0 比特和 padding bits(即可能把填充的 0 中前四个视为一个 terminator,把后面的 0 才视为属于 padding bits )
「QRCode 标准阅读」#1 构成及数据编码