基于Excel的QR二维码生成工具——原理及算法详解(之三)

来源:互联网 发布:apache 2.0 开源协议 编辑:程序博客网 时间:2024/05/22 16:42

在上一篇文章中我们讨论了使用工作表函数计算RS码的算法,接下来,我们将讨论生成多项式的计算以及RS码计算的VBA算法。在已经有了工作表函数计算RS码的情况下,还要探讨使用VBA的原因是因为VBA的计算速度比工作表函数快得多。

在开始探讨生成多项式之前,必须要说明的是,在QR码标准GB18284-2000的附录中已经附带了所有在QR计算中可能会需要的生成多项式,甚至不需要的都一并附上了:
这里写图片描述
但是,有意思的是,RS码的生成多项式其实并不止一个,而且QR标准中给出的并不是标准生成多项式。我尝试了使用标准生成多项式所计算的纠错码,将其填充到QR矩阵中后,同样能够正确解码而且能够正确地纠错。因此,如果没有耐心,只想寻求干货的同学可以绕过这一段,而有兴趣的同学可以一起探讨一下,使用不同的生成多项式来创建与QR标准中完全不同的二维码。

我们知道标准生成多项式的公式为:

g(x)=(x+a)(x+a 2 )(x+a 3 )(x+a nk ) 
,从这个公式可以看出来其实这是一个非常典型的递进算法,如果令nk=v ,且另上式为g v (x) ,那么我们可以看到:
g 1 (x)=(x+a) 
g 2 (x)=(x+a)(x+a 2 )=g 1 (x)(x+a 2 ) 
以至于一般地
g v (x)=g v1 (x)(x+a v ) 

我们可以如同上一节中一样,将上述多项式的计算通过一个表格来实现:

v= x 的幂次 x 0   x 1   x 2   x 3   x 4   x 5   g 1 (x)  a 的幂次 1 0 乘数 a 的幂次 2 0

上表中使用不同的列代表多项式的不同次数的项,并且将系数写到单元格中,可见第二行表示的就是g 1 (x) ,因为这个多项式的x 0  项系数为a 的1次幂,而x 1  项系数为a 的0次幂,也就是(x+a) 。同理,“乘数”行表示的多项式就是(x+a 2 ) 了。那么要计算g 2 (x) 需要用乘数乘以g 1 (x) ,在表格中就是用乘数的所有系数分别乘以g 1 (x) 的所有系数,并且进行恰当的移位:

v= x 的幂次 x 0   x 1   x 2   x 3   x 4   x 5   g 1 (x)  a 的幂次 1 0 乘数 a 的幂次 2 0 g 1 (x) 乘以2 a 的幂次 3 2 g 1 (x) 乘以0 a 的幂次 1 0 g 2 (x)  a 的幂次 3 26 0

上表中表示了这样的计算,请注意g 1 (x) 乘以0的结果是向右移位的,这是因为“0”项的次数为1,因此乘以g 1 (x) 以后会使它的多项式所有项的幂次升高一次,在表格上就表示为右移一位。然后将两次计算的结果相加,就得到了g 2 (x) 的多项式

同理我们可以用上面的表格计算g 3 (x) 乃至于g v (x) 

v= x 的幂次 x 0   x 1   x 2   x 3   x 4   x 5   g 2 (x)  a 的幂次 3 26 0 乘数 a 的幂次 3 0 g 2 (x) 乘以3 a 的幂次 6 29 3 g 2 (x) 乘以0 a 的幂次 3 26 0 g 3 (x)  a 的幂次 6 201 199 0

在Excel中可以很容易根据上面的表格来构造g(x) 的计算公式矩阵:
$g(x)$计算

需要注意的是,在上面的算法中表格的最左列是x 的最低次幂,而在RS计算表格中,最左列是x 的最高次幂,因此在使用计算结果的时候,需要进行一次倒序,同时还需要将a 的幂次转化成系数才行

好了,现在我们已经完成了生成多项式的构造,并且探讨了RS码的表格式计算算法。已经完全可以开始进行QR的制作了么?不,没那么简单,使用工作表函数的RS码在进行小规模计算时,计算速度是完全可以胜任的,但是,如果填充的是高版本的QR码,计算量就非常可观了。通常情况下,一个QR码需要对长达上百位的数据码计算30个纠错码,并且因为QR的分段设计,同样的纠错码计算需要重复几十次,这样就导致计算表十分庞大,计算次数达到上百万次。我验证了一下,这样的表格在我的电脑上需要大约25秒才能完成计算,不具备实用性。因此,下面的VBA代码被用来实现同样的RS计算功能,但结果可以瞬间得到:

Private Function ECCALC(dataWords, N, k, gp)' function that calculates error correction code of the input code words by generate polynomial' codewords as first argument is the code word for which EC code is calculated' n as second argument total number of code words' k as third argument defines the number of data code words, thus n-k is the number of error correction code words' output of the function is also defined as an array that contains the error correction code' the error correction code is calculated on the galois field with primitive polynomial= x^8+x^4+x^3+x^2+1=0'Dim gpWords(), cWords(), dWords(), prod() As LongReDim gpWords(N - k), cWords(N), dWords(N), prod(N - k)Dim divider As LongDim num, EC As VariantDim i,j As Long    With Sheets("RS Calc")        For i = 0 To 254            GF(i) = .Cells(7, i + 6)            GFP(i) = .Cells(8, i + 6)        Next    End With    'read genpoly    i = 0    For Each num In dataWords        If IsNumeric(num) Then            cWords(i) = num            i = i + 1        End If    Next    i = 0    For Each num In gp        If IsNumeric(num) Then            gpWords(i) = num            i = i + 1        End If    Next    'RS calculation starts    For i = 0 To k - 1        divider = cWords(0)        For j = 0 To N - 2     'calculate next code words by multiply genopoly with divider, and substract code word            If j < N - k And divider <> 0 Then                num = cWords(j + 1) Xor nGfMult(divider, gpWords(j + 1))            Else                num = cWords(j + 1) Xor 0            End If            cWords(j) = num        Next    Next    ECCALC = cWords    End Function
阅读全文
1 0
原创粉丝点击