QR code 二维码基础入门教程(二)
承接上文,让我们继续下面的步骤
纠错码编码
先说说纠错容量
- 纠错码可以纠正两种错误:
- 拒读错误(错误码位置已知),是一个没有扫到或者无法译码的符号字符,需要一个纠错码
- 替代错误(错误码位置未知),是一个错误译码的符号字符,需要两个
- 数量公式:
e+2t≤d−p
e
+
2
t
≤
d
−
p
,其中
- e e 为拒读错误数
- 为替代作物数
- d d 为纠错码字数
- 为错误检测码字数(1-L时p=3,1-M和2-L时p=2,1-H、1-Q、和3-L时,p=1,其余p=0)
- 举个例子:版本6-H,有112个纠错码(查表 error correction table,定位6-H,28*4=112),数据容量为60个码字,共172个码字。那么112个纠错码可以纠正56个替代错误或者112个拒读错误,纠错容量为 56/172 = 32.6%
Step 1 将数据码字进行分组
- 根据 error correction table 将数据进行分块,下面举个例子
- 一个数据经过以5-Q形式进行数据编码后如下,共62个码字
(codeword #1) 01000011
(codeword #2) 01010101
(codeword #3) 01000110
(codeword #4) 10000110
(codeword #5) 01010111
(codeword #6) 00100110
(codeword #7) 01010101
(codeword #8) 11000010
(codeword #9) 01110111
(codeword #10) 00110010
(codeword #11) 00000110
(codeword #12) 00010010
(codeword #13) 00000110
(codeword #14) 01100111
(codeword #15) 00100110
(codeword #16) 11110110
(codeword #17) 11110110
(codeword #18) 01000010
(codeword #19) 00000111
(codeword #20) 01110110
(codeword #21) 10000110
(codeword #22) 11110010
(codeword #23) 00000111
(codeword #24) 00100110
(codeword #25) 01010110
(codeword #26) 00010110
(codeword #27) 11000110
(codeword #28) 11000111
(codeword #29) 10010010
(codeword #30) 00000110
(codeword #31) 10110110
(codeword #32) 11100110
(codeword #33) 11110111
(codeword #34) 01110111
(codeword #35) 00110010
(codeword #36) 00000111
(codeword #37) 01110110
(codeword #38) 10000110
(codeword #39) 01010111
(codeword #40) 00100110
(codeword #41) 01010010
(codeword #42) 00000110
(codeword #43) 10000110
(codeword #44) 10010111
(codeword #45) 00110010
(codeword #46) 00000111
(codeword #47) 01000110
(codeword #48) 11110111
(codeword #49) 01110110
(codeword #50) 01010110
(codeword #51) 11000010
(codeword #52) 00000110
(codeword #53) 10010111
(codeword #54) 00110010
(codeword #55) 11100000
(codeword #56) 11101100
(codeword #57) 00010001
(codeword #58) 11101100
(codeword #59) 00010001
(codeword #60) 11101100
(codeword #61) 00010001
(codeword #62) 11101100 - 查表得,5-Q需要将数据分为2个Group,第一个Group有2个Block(15个码字),第二个Group有2个Block(16个码字)
- 进行分组,得到如下表
- 一个数据经过以5-Q形式进行数据编码后如下,共62个码字
Group Number | Block Number | Data Codewords in the Group |
---|---|---|
Group 1 | Block 1 | (codeword #1) 01000011 (codeword #2) 01010101 (codeword #3) 01000110 (codeword #4) 10000110 (codeword #5) 01010111 (codeword #6) 00100110 (codeword #7) 01010101 (codeword #8) 11000010 (codeword #9) 01110111 (codeword #10) 00110010 (codeword #11) 00000110 (codeword #12) 00010010 (codeword #13) 00000110 (codeword #14) 01100111 (codeword #15) 00100110 |
Block 2 | (codeword #16) 11110110 (codeword #17) 11110110 (codeword #18) 01000010 (codeword #19) 00000111 (codeword #20) 01110110 (codeword #21) 10000110 (codeword #22) 11110010 (codeword #23) 00000111 (codeword #24) 00100110 (codeword #25) 01010110 (codeword #26) 00010110 (codeword #27) 11000110 (codeword #28) 11000111 (codeword #29) 10010010 (codeword #30) 00000110 | |
Group 2 | Block 1 | (codeword #31) 10110110 (codeword #32) 11100110 (codeword #33) 11110111 (codeword #34) 01110111 (codeword #35) 00110010 (codeword #36) 00000111 (codeword #37) 01110110 (codeword #38) 10000110 (codeword #39) 01010111 (codeword #40) 00100110 (codeword #41) 01010010 (codeword #42) 00000110 (codeword #43) 10000110 (codeword #44) 10010111 (codeword #45) 00110010 (codeword #46) 00000111 |
Block 2 | (codeword #47) 01000110 (codeword #48) 11110111 (codeword #49) 01110110 (codeword #50) 01010110 (codeword #51) 11000010 (codeword #52) 00000110 (codeword #53) 10010111 (codeword #54) 00110010 (codeword #55) 11100000 (codeword #56) 11101100 (codeword #57) 00010001 (codeword #58) 11101100 (codeword #59) 00010001 (codeword #60) 11101100 (codeword #61) 00010001 (codeword #62) 11101100 |
- 查表可知5-Q中每个块有18个纠错码,因此一共是18*4=72个纠错码
Step 2 理解多项式长除法
- 这个比较简单,以
(x+1)√(3x2+x−1)
(
x
+
1
)
√
(
3
x
2
+
x
−
1
)
$为例
最终结果是 3x+2 3 x + 2 ,余数为1(特别的,就是 1x^0)
Step 3 理解Galois Field
- 说实话,我看了一些博客还是不理解这个。暂时认为,任意的两个数在这个域中,那么它们的数学运算结果也在这个域中。
- QR 标准中使用位的模2算法和字节模100011101,这种情况下我们称使用了Galois Field 28 2 8 ,或者GF(256)
- GF(256)包括256个数字 0….255,所有在GF(256)的数学操作的结果都会落在0…255中
Step 4 理解Galois Field算术
- 运算结果如果大于255,那么需要做取模操作,这样使得结果人在GF中
- 在GF中, −n=n − n = n ,因此加法和减法是一样的
- 位模2,其实就是XOR,举例:
- (1 + 1)%2 == (1 XOR 1) == 0
- (1 + 0)%2 == (1 XOR 0) == 1
- (0 + 0)%2 == (0 XOR 0) == 0
Step 5 利用逐字节100011101取模,生成2的乘幂
- 我们想做这样一件事情,用
2n
2
n
表示[0,255]中的所有数,例如用
20=1
2
0
=
1
,
22=4
2
2
=
4
。那么我们有2的0次方到8次方为:
- 20=1 2 0 = 1
- 21=2 2 1 = 2
- 22=4 2 2 = 4
- 23=8 2 3 = 8
- 24=16 2 4 = 16
- 25=32 2 5 = 32
- 26=64 2 6 = 64
- 27=128 2 7 = 128
- 28=256 2 8 = 256
- 当 n≥8 n ≥ 8 时, 2n>255 2 n > 255 ,超出了 [0,255] [ 0 , 255 ] 的范围,因此当 2n>255 2 n > 255 时,我们要对 2n 2 n 用 100011101 取模。100011101 也就是十进制 285。换句话说, 28=256mod285=29 2 8 = 256 mod 285 = 29 。
- 注意,当我们计算
29
2
9
时,并不是用 512 去 XOR 285,而是用
29=28∗2=29∗2=58
2
9
=
2
8
∗
2
=
29
∗
2
=
58
得到结果。
我们继续举一些例子来说明计算方式:
210=29∗2=58∗2=116 2 1 0 = 2 9 ∗ 2 = 58 ∗ 2 = 116
211=210∗2=116∗2=232 2 11 = 2 10 ∗ 2 = 116 ∗ 2 = 232
212=211∗2=232∗2=464mod285=205 2 12 = 2 11 ∗ 2 = 232 ∗ 2 = 464 mod 285 = 205
只要超过了 255,那么就做 100011101 的 XOR(即取模于 285)
Step 6 利用逐字节100011101取模,生成2的乘幂
- Step 5 让 [0,255] [ 0 , 255 ] 所有的数都被表示成 2n 2 n ,这可以用 logs 和 antilogs 来简化 GF(256) 中的乘法操作。
- 基本知识: 2n∗2m=2m+n 2 n ∗ 2 m = 2 m + n 。举例 22∗28=210,2170∗2164=2334=2334mod255=279 2 2 ∗ 2 8 = 2 10 , 2 170 ∗ 2 164 = 2 334 = 2 334 mod 255 = 2 79
Step 7: 理解生成器多项式
- 首先要确定纠错码码字的个数。例如 5-Q 有 72 个,1-L 有 7 个。
- 接下来有点复杂,请看 原文,耐心一点看例子,不难的。
- 生成器多项式只与纠错码码字的个数有关,因此是可以预先生成的。这里有个神奇的 链接 可以生成生成器多项式
Step 8: 生成纠错码码字
- 我们利用多项式除法来生成纠错码码字。我们需要两个多项式:消息多项式和生成器多项式。用消息多项式除以生成器多项式,得到的余数结果即为纠错码码字。
- 进行多项式除法之前,消息多项式先乘上 xn x n ,其中 n n 是纠错码的个数,这样保证消息多项式足够大进行除法。
Step 9: 消息多项式除以生成器多项式
- 第一步:生成器多项式乘上消息多项式的头一项。
- 第二步:将生成器多项式中的 转为 [0,255] [ 0 , 255 ] 的数字。
- 第三步:进行多项式除法。
- 重复 1~3 步,共进行 m 次,其中 m 为数据码字的个数。
- 最终得到余数,即纠错码码字。具体过程参看 Show polynomial division steps