「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
    • 所以最终的比特流: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 ……

数字模式(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
    • 完整数据比特流: 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
    • 完整数据比特流: 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 第二个表规定)的后面。

Latin-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)

转换后的数据比特流还需要填充至二维码的数据容量

  1. 首先先用 0 补充比特流长度到 8 的整数倍
  2. 然后用 1110110000010001 交替填补到二维码数据容量

具体的数据容量由版本号和纠错等级决定,且数据容量(比特)一定为8的倍数,完整数据见文档的 33~36 页(整个 pdf 的第 41~44 页)

注:这个地方 QRazyBox 网站存在 bug,有时无法正常识别填充的 0 比特和 padding bits(即可能把填充的 0 中前四个视为一个 terminator,把后面的 0 才视为属于 padding bits )


未完待续……「QRCode 标准阅读」#2 纠错码编码与图像生成

「QRCode 标准阅读」#1 构成及数据编码

https://blog.tonycrane.cc/p/1c1e6bbc.html

作者

TonyCrane

发布于

2021-11-30

更新于

2021-12-01

许可协议

评论