基于Excel的QR二维码生成工具

您所在的位置:网站首页 二维码刷新原理图解大全 基于Excel的QR二维码生成工具

基于Excel的QR二维码生成工具

2024-07-12 21:15| 来源: 网络整理| 查看: 265

在上一篇文章以及相关的两篇文章中,我们探讨了QR二维矩阵码生成过程中最关键的部分:里德所罗门纠错码(RS码)的生成原理及生成算法,不但涵盖了RS码的计算部分,同时还讨论了生成多项式、以及伽罗华域的相关理论,同时给出了Excel工作表函数的算法以及VBA算法代码。搞定了RS纠错码的计算,可以说QR码的生成工作就完成了大半了,因为剩余的部分都可以从QR Specification中得到很详尽的解释和示例。

从这篇文章开始,我们将按照顺序逐一讨论QR二维码生成过程中的各大步骤:

数据编码——讨论不同的数据码字类型,以及一种Excel工作表函数算法生成数据编码数据编码——讨论混合数据码字的生成,并给出一种能够进行混合编码的VBA算法版本及格式数据——使用BCH纠错码计算版本及掩码纠错码二维码填充——二维码的填充方式,讨论VBA填充算法1:寻址法二维码填充——讨论VBA填充算法2:逐列法

因此,从本文开始,我将用五篇文章来逐一讨论上面的内容,本文的主要目的将讨论QR码的数据编码。

从QR标准文件中可以知道,标准的QR二维码是一个类似于下图的图形(另外还有一种模式的“MicroQR”并不在本文探讨范围内): QR二维码示例 在这样一个由深浅两色组成的正方形位图区域内,除了部分预留区域被用来填充固定的功能性图形以外,剩下的区域就是数据区域,所有的数据在被编码、再添加纠错码并分组乱序后,从最右下角开始,按照特定的顺序填充整个数据区域。最后覆盖上掩码,就成了最终的二维码图形。下图画出了所有的功能性图形和数据区域: 图片来自于ISO18004-2006 * 上图来自于ISO18004-2006 另外QR二维码有40个版本,版本数越大,码形尺寸也就越大,同时容纳的数据量也就越多。具体的图形信息大家可以参考标准文件,在此不再赘述。我们关注的是如何将数据编码。

国际标准的QR码有几种通用的编码形式,而中文汉字是在QR码的国标中规定了具体的编码形式。之所以QR码有多种不同的编码方式,主要目的是为了缩短编码的长度,从而增加二维码的容量。同时,为了实现混合编码,QR规范中也详尽规定了编码的具体结构:

字符编码段模式指示符字符计数指示符数据位流终止符第一段001000000010100111001010000101110010第二段11010001000000100101101010101000001011110终止符0000

上表显示了一条典型的完整数据编码码流,可以看出这条编码码流由两段组成,第一段是“字母数字”模式的编码,字符数量为5个字符,而第二段为“中国汉字”模式的编码,字符的数量为2个字符,两段编码分别以相应的模式指示符打头,继而连接字符计数指示符,最后跟上数据编码码流。当所有的编码段全部结束后,最后跟上“0000”终止符代表编码码字的结束。不过这里需要注意的是,终止符在解码的过程中并不起作用,只是用来填充数据位以保证整个码流能够正好分成8位字节的,因此可以被截短,也可以接续更多的“0”以补充到足够的位数。下面,就以一个简单的例子来解释Excel工作表函数的编码过程:

例如,现在需要将字符串“ABC23”编码,编码模式为字母数字,QR的版本为1-M。针对这样的编码,在Excel中我采用的方法是使用字符串和0~255的十进制数同时作为编码的输出,含有“0”或者“1”的字符串用来进行二维码的填充,使用Mid函数来取出相应的“0/1”值,而0~255的十进制数则被用来计算RS纠错码(计算RS纠错码的算法已经在前面两篇文章中解释过了) 因此,在Excel中,上述例子的编码过程如下: 1. 将字符串两两分组,放入一列单元格中,很容易通过Mid函数实现:“AB”,“C2”, “3” 2. 将分组后的字符分别编码,通过Vlookup函数从编码表中查找字符的编码值,并根据QR规范计算编码,同时转化为11位或6位0/1字符串:

“AB” -> 10*45+11 = 461 -> “00111001101”“C2” -> 12*45+2 = 542 -> “01000011110”

“3” -> 3 ->”000011” 3

在生成的字符串前面加上模式指示符和字数指示符(均为字符串形式,使用”&”连接,或使用Concaternate函数),同时,由于数据码流的长度不能被8整除,后面需要添加三个“0”以补足: 模式指示符字数指示符数据编码终止符补位符001000000010100111001101010…00110000000

4. 再将字符编码分成8位一组,使用Mid函数,=MID(“数据码流”,i*8-7,8),其中“i”为数据码的组数

第1组第2组第3组第4组第5组第6组001000000010100111001101010000111100000110000000324120557193128

5. 由于编码用于填充1-M版本的QR码,这个版本的码字可以容纳128个bit,而数据编码长度不够,因此后面还需要添加上填充字符(236和17所代表的二进制数反复重复直到填满整个QR)。这样,整个数据编码就完成了:

组1组2组3组4组5组6组7组8组9组10组11组12组13组14组15组163241205571931282361723617236172361723617

完成上述编码后,就可以应用前面文章所讨论的RS纠错码生成算法计算码流的纠错码,通过QR规范可以查到,1-M版本的QR码所对应的RS纠错码为 RS(26,16)  RS(26,16)也就是10个纠错码,根据QR规范中给出的生成多项式 可以直接计算纠错码,当然,小伙伴们也可以自己计算标准生成多项式,并用来计算纠错码,这样可以得出一个完全不同的纠错码,但是,两个纠错码都可以被正常填充并纠错:

g(x)  g(x)EC1EC2EC3EC4EC5EC6EC7EC8EC9EC10QR规范73134125491391662986171126标准计算218105252331417171200199184

根据上面的例子,可以很容易构造一张计算工作表,将字符串转化为数据码流和字符串,如下图: Excel 中的数据编码 中文汉字和8位字节编码的构造方式与字母数字模式类似,不同的是8位字节模式直接使用字符的ASCII码作为字符编码,使用上简单一些,而中文汉字的编码如下: 1. 将每一个中文汉字编码为GB2312双字节编码(两个0~255之间的数字,QR规范上使用十六进制数&H0~&HFF,这里统一使用十进制),记为 x 1   x_1与 x 2   x_2 2. 令最终编码为 y  y,如果第一个汉字的编码在161到170之间时:

y=(x 1 −161)∗96+(x 2 −161) y = (x_1-161)*96+(x_2-161),再将 y  y编码为13位二进制数编码串 3. 如果第一个汉字的编码在176到250之间时,y=(x 1 −166)∗96+(x 2 −161) y = (x_1-166)*96+(x_2-161),再将 y  y编码为13位二进制数编码串

在此做一些补充: 在上面的例子中,将十进制编码转为二进制并转为字符串时,如果使用工作表函数,由于Dec2Bin函数最多只能转化512以内的十进制整数,超过512只能得到“#NUM!”的结果,因此需要使用下面的表格来进行十进制到二进制的转换(这个转换表没有位数的限制,当然,使用VBA写自定义函数也是可以的) 十进制到二进制转换 如上图所示,在左边的Input area中,逐位判断输入数值是否大于表头的二进制数,是则表示该二进制数位为1,否则为0。若该位为1,则用输入数减去表头二进制数作为新的输入数,进行下一位计算,一直到数字为0为止。右边部分则是简单的条件判断,判断该二进制数位为0还是1.然后将所有二进制位连接起来做成字符串,就成为最左列的输出字符串。

上面的计算表在VBA中可以写成工作表函数调用,效果也是一样的:

Private Function Sdec2bin(n As Long, l As Long) As String Dim char As String * 1, str As String Dim i As Long For i = l To 1 Step -1 char = IIf((n And 2 ^ i) = 0, "0", "1") str = str + char Next Sdec2bin = str End Function

至此,我们已经讨论了QR码的数据编码的具体实现过程,数据被编码后首先被转换为“0/1”字符串并被连接起来,每8bit分组后再被转换为一组0~255的数值数据以便计算RS纠错码,计算完成后再次被转化为字符串形式,以便未来被用来进行二维码单元格区域的填充。但是,通过工作表函数来进行数据编码有一个极大的弱点,那就是很难实现不同模式的混合编码,而且公式实现比较复杂。在下一篇文章中,我们还将继续讨论 数据编码的问题,并讨论一个VBA算法,用来解决混合编码的问题



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3