QRCode - 二维码小记

SonderLau ... 2022-02-06 Projects
  • Qrcode
  • Python
大约 4 分钟

# QRCode - 二维码小记

家里人需要我做一个二维码,别人可疑通过扫码来联系挪车。就是把电话的联系方式放到上面

# 使用场景

仅仅是做一个扫码获得手机号的话是比较简单的,对于手机而言只要将:

TEL:133-1234-1234
1

这样的字符串编码成二维码扫码就能使用了。

但实际上大家在日常扫描二维码的时候都会使用 微信 进行扫码,所以要考虑微信扫出来能执行的。

事实上微信如果能通过二维码识别的结果就调用系统的电话程序是不太安全的,同时也有可能对用户造成一定的骚扰,因此简单这样是不行的。

后面看到了微信支付的二维码规范 (opens new window) 其中有提到一个 名片二维码国家标准 (opens new window)

# 开整

在国家标准中,对于电子名片有三个格式,包括 CARD VCARD MECARD,不同的格式对应着字段名称和数据格式的不同。

我实测使用 CARD 格式的内容微信仍然会识别为文字。

MECARD 没有测试,我直接选用的 VCARD

我选择的理由很简单,我的手机自带一个分享通讯录中联系人名片的功能。它生成的二维码我识别之后就是 VCARD 格式,我想这个应该更通用一些。

BEGIN:VCARD
VERSION:3.0
FN:刘先生
N:刘;生;先;;
TEL;TYPE=CELL:133 1234 1234
END:VCARD
1
2
3
4
5
6

# 问题

我进行了如下的操作:

  • 使用手机自带的通讯录功能导出我的一个联系人的二维码名片
  • 扫描二维码获得二维码中的字符串,并不执行名片相关的动作
  • 对字符串进行二维码生成
  • 比对手机和我生成的二维码

在我自己生成二维码这一步我开始直接使用的网上提供的在线开箱即用的工具。

我发现这两个二维码的复杂度差得比较多,肉眼可见的那种。

我仔细调整这两个二维码在我屏幕上的尺寸大小,试图让我的比对更准确一些。

我发现我自己生成的二维码确实“更复杂”一些。

但是我对这两个二维码都进行扫描,会得到相同的字符串,引起了我的注意。

虽然不影响使用,但是我还是感觉这其中有一些我不太懂的东西在里面。

# 捋清思路

于是我把那两个识别出来的结果的字符串使用 diff 工具进行比对,发现我手机生成出来的部分的换行符号是 \r\n 而我用网页生成的换行符号是 \n,但是有些行的换行符后面会有多个换行

为了解决这个问题,我得从新浏览一遍二维码的生成过程。

我注意到二维码有一个纠错码部分(Error correction code),有 L M Q H 四个等级。

分别对应着更多的可以被修正的比例,但是也会增加生成出来的二维码复杂程度。

于是我就使用最低级的 L 级别生成二维码,生成出来的结果就比较相似了。


后来我发现二维码生成时会考虑一个东西,Version, 不同的版本之间的尺寸是不同的。

一共是有 40 个版本,Version 1 = 21 x 21,Version 2 = 25 x 25

他们的计算式子:

Size=(Version1)×4+21Size = (Version - 1) \times 4 + 21

比如我的内容生成出来的信息量使用 版本 1 不太够,版本 2 比较富裕,为了保证信息能完整的显示,我们就必须选用 版本 2,同时会对信息进行填充达到版本 2 的最大信息量,也就是补 0。

而我自己生成的符号中,使用了更高的纠错率,但是字符的数量使得生成的时候不得不上升一个版本,让最后生成出来的二维码显得更“复杂”了。

# 结论

  • 仔细阅读对应的格式的文档,对于换行等特殊字符,尽量用 \n 而不是键盘的回车,因为不同平台可能会导致差异。

  • 容错码并不是越大反而越好。在打印出来的图案尺寸一定的情况下,二维码图形越复杂,单位面积丢失的数据反而也越多,可能会得不偿失

    关于该结论暂无理论上的结果,也许以后有兴趣可能会出一期?

  • 关注输出的 Version