基于Excel的QR二维码生成工具——原理及算法详解(之四)
来源:互联网 发布:钥匙包 淘宝 编辑:程序博客网 时间:2024/06/05 11:50
在上一篇文章以及相关的两篇文章中,我们探讨了QR二维矩阵码生成过程中最关键的部分:里德所罗门纠错码(RS码)的生成原理及生成算法,不但涵盖了RS码的计算部分,同时还讨论了生成多项式、以及伽罗华域的相关理论,同时给出了Excel工作表函数的算法以及VBA算法代码。搞定了RS纠错码的计算,可以说QR码的生成工作就完成了大半了,因为剩余的部分都可以从QR Specification中得到很详尽的解释和示例。
从这篇文章开始,我们将按照顺序逐一讨论QR二维码生成过程中的各大步骤:
- 数据编码——讨论不同的数据码字类型,以及一种Excel工作表函数算法生成数据编码
- 数据编码——讨论混合数据码字的生成,并给出一种能够进行混合编码的VBA算法
- 版本及格式数据——使用BCH纠错码计算版本及掩码纠错码
- 二维码填充——二维码的填充方式,讨论VBA填充算法1:寻址法
- 二维码填充——讨论VBA填充算法2:逐列法
因此,从本文开始,我将用五篇文章来逐一讨论上面的内容,本文的主要目的将讨论QR码的数据编码。
从QR标准文件中可以知道,标准的QR二维码是一个类似于下图的图形(另外还有一种模式的“MicroQR”并不在本文探讨范围内):
在这样一个由深浅两色组成的正方形位图区域内,除了部分预留区域被用来填充固定的功能性图形以外,剩下的区域就是数据区域,所有的数据在被编码、再添加纠错码并分组乱序后,从最右下角开始,按照特定的顺序填充整个数据区域。最后覆盖上掩码,就成了最终的二维码图形。下图画出了所有的功能性图形和数据区域:
* 上图来自于ISO18004-2006
另外QR二维码有40个版本,版本数越大,码形尺寸也就越大,同时容纳的数据量也就越多。具体的图形信息大家可以参考标准文件,在此不再赘述。我们关注的是如何将数据编码。
国际标准的QR码有几种通用的编码形式,而中文汉字是在QR码的国标中规定了具体的编码形式。之所以QR码有多种不同的编码方式,主要目的是为了缩短编码的长度,从而增加二维码的容量。同时,为了实现混合编码,QR规范中也详尽规定了编码的具体结构:
上表显示了一条典型的完整数据编码码流,可以看出这条编码码流由两段组成,第一段是“字母数字”模式的编码,字符数量为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”以补足:
4. 再将字符编码分成8位一组,使用Mid函数,=MID(“数据码流”,i*8-7,8),其中“i”为数据码的组数
5. 由于编码用于填充1-M版本的QR码,这个版本的码字可以容纳128个bit,而数据编码长度不够,因此后面还需要添加上填充字符(236和17所代表的二进制数反复重复直到填满整个QR)。这样,整个数据编码就完成了:
完成上述编码后,就可以应用前面文章所讨论的RS纠错码生成算法计算码流的纠错码,通过QR规范可以查到,1-M版本的QR码所对应的RS纠错码为
可以直接计算纠错码,当然,小伙伴们也可以自己计算标准生成多项式,并用来计算纠错码,这样可以得出一个完全不同的纠错码,但是,两个纠错码都可以被正常填充并纠错:
根据上面的例子,可以很容易构造一张计算工作表,将字符串转化为数据码流和字符串,如下图:
中文汉字和8位字节编码的构造方式与字母数字模式类似,不同的是8位字节模式直接使用字符的ASCII码作为字符编码,使用上简单一些,而中文汉字的编码如下:
1. 将每一个中文汉字编码为GB2312双字节编码(两个0~255之间的数字,QR规范上使用十六进制数&H0~&HFF,这里统一使用十进制),记为
2. 令最终编码为
3. 如果第一个汉字的编码在176到250之间时,
在此做一些补充:
在上面的例子中,将十进制编码转为二进制并转为字符串时,如果使用工作表函数,由于Dec2Bin函数最多只能转化512以内的十进制整数,超过512只能得到“#NUM!”的结果,因此需要使用下面的表格来进行十进制到二进制的转换(这个转换表没有位数的限制,当然,使用VBA写自定义函数也是可以的)
如上图所示,在左边的Input area中,逐位判断输入数值是否大于表头的二进制数,是则表示该二进制数位为1,否则为0。若该位为1,则用输入数减去表头二进制数作为新的输入数,进行下一位计算,一直到数字为0为止。右边部分则是简单的条件判断,判断该二进制数位为0还是1.然后将所有二进制位连接起来做成字符串,就成为最左列的输出字符串。
上面的计算表在VBA中可以写成工作表函数调用,效果也是一样的:
Private Function Sdec2bin(n As Long, l As Long) As StringDim char As String * 1, str As StringDim i As Long For i = l To 1 Step -1 char = IIf((n And 2 ^ i) = 0, "0", "1") str = str + char Next Sdec2bin = strEnd Function
至此,我们已经讨论了QR码的数据编码的具体实现过程,数据被编码后首先被转换为“0/1”字符串并被连接起来,每8bit分组后再被转换为一组0~255的数值数据以便计算RS纠错码,计算完成后再次被转化为字符串形式,以便未来被用来进行二维码单元格区域的填充。但是,通过工作表函数来进行数据编码有一个极大的弱点,那就是很难实现不同模式的混合编码,而且公式实现比较复杂。在下一篇文章中,我们还将继续讨论
数据编码的问题,并讨论一个VBA算法,用来解决混合编码的问题
- 基于Excel的QR二维码生成工具——原理及算法详解(之四)
- 基于Excel的QR二维码生成工具——原理及算法详解(之二)
- 基于Excel的QR二维码生成工具——原理及算法详解(之三)
- 基于Excel的QR二维码生成工具——原理及算法详解(之五)
- 基于Excel的QR二维码生成工具——原理及算法详解(之六)
- 基于Excel的QR二维码生成工具——原理及算法详解(之七)
- 基于Excel的QR二维码生成工具——原理及算法详解(之一)
- 基于Excel的QR二维码生成工具——原理及算法详解(最终篇)
- 二维码(QR code)基本结构及生成原理
- 二维码(QR code)基本结构及生成原理
- QR的生成(二维码)
- Android应用--QR的生成(二维码)
- Android应用--QR的生成(二维码)
- Android应用--QR的生成(二维码)
- Android应用--QR的生成(二维码)
- 安卓系统下生成QR码(二)——自定义二维码的纠错等级
- 安卓系统下生成QR码(三)——自定义二维码的颜色
- Javascript生成二维码(QR)
- LaTex
- 全文搜索技术
- Variance
- Java数据结构---数组
- adduser 显示和不显示
- 基于Excel的QR二维码生成工具——原理及算法详解(之四)
- Http Header信息
- INTELLIJ IDEA 鼠标放上去提示参数
- iOS 创建pch文件Xcode9.0
- 2-sat
- Java并发总结
- 数据结构之线性表---顺序表
- Android Studio 3.0 及个版本下载和 gradle 各版本下载
- MVVMLight的使用方法