如何优化二维码,使其更容易被识别?
微wx笑 2021-11-28【见闻】 5 0关键字: 二维码
澳大利亚政府一直在告诉我们彼此保持距离。令人惊讶的是,同一个政府同时发布了要求人们不必要地靠近的海报。它们包含用于联系人跟踪签到的二维码,这些二维码又小又密,这意味着
澳大利亚政府一直在告诉我们彼此保持距离。令人惊讶的是,同一个政府同时发布了要求人们不必要地靠近的海报。它们包含用于联系人跟踪签到的二维码,这些二维码又小又密,这意味着它们很难扫描。他们怎么可能更好?
就是这样:
标有“现在有效”的中央标签可以立即推出。现有的原生应用程序可以理解那张海报,所以如果新南威尔士州政府转而发布类似的东西,每个人的生活都会神奇地变得更轻松。“优化”海报展示了如果 QR 码被优化到极致,当该功能最初部署到应用程序中时可能会发生什么。
在本文中,我们将介绍如何达到这一点,涉及:
当前值机二维码的内容及其功能
二维码的工作原理(纠错、版本和编码模式)
优化存储在二维码中的数据的演练
这些二维码的安全性
让我们通过查看这个特定示例来学习使用/设计 QR 码的一些一般课程。
你在写什么?
几乎新南威尔士州甚至澳大利亚各地的每个店面都有一个 A4 页面,里面隐藏着一个二维码。进入的客户需要扫描以注册他们的存在以进行联系人跟踪,这(如果他们已安装)将他们推送到 Service NSW 应用程序中。该设计在某些方面很聪明,但在其他方面似乎并不那么聪明。
签到海报和扫描后的 Service NSW 应用程序视图。点按可单独查看海报 (PDF)。
为了适应所有这些,它必须是密集的:它的每一边都有 81 个模块(小方块),这意味着它的版本是 16。
参数的eyJ0…fQ==
值data
看起来可能是用base64编码的,实际上,如果我们尝试在该假设下对其进行解码,我们会发现一些结构化的 JSON:
{ "t": "covid19_business", "bid": "121321", "bname": "Test NSW Government QR code", "baddress": "Business address goes here " }
把这些关键点变成文字,我们可以猜测每个二维码告诉我们:
t
:这是一个 COVID-19 入住代码bid
:业务的标识符bname
: 企业名称baddress
:公司地址(这是一个测试二维码,但在实际二维码中,它看起来像“123 Street, Suburb NSW”)
评估
这些二维码海报有一些很棒的属性:
它们根本存在:在新南威尔士州服务部代码推出并强制执行之前,接触者追踪情况一团糟。一些场地需要手写输入,其他场地需要将个人信息输入到随机网站(不同易用性)中。现在,它是一个可以记住您的详细信息的应用程序。
使用 URL(而不仅仅是原始数据)意味着它们可以被任何扫描仪有用地解释,例如手机的相机,而不需要使用特定的应用程序进行扫描。
有一个本机应用程序理论上可以用于在没有互联网访问时进行离线签到,以便以后同步……尽管这在实践中实际上并不能使用当前的应用程序。二维码包含足够的信息,仍然可以向用户显示确认信息,因此他们知道他们扫描了他们期望的内容。
使用高误差校正意味着它们理论上可以抵抗“损坏”,例如层压板或窗户的反射,甚至灰尘和孔洞。
海报解释了如何扫描代码(现在看起来不可思议,但这些代码被引入了一个二维码无法立即识别的世界)。
Service NSW 应用程序会在签到时显示场地名称,即使离线也是如此。
另一方面,他们可以做得更好:
二维码在物理上很小。
使用最高级别的纠错可能会让事情变得有点远。
可以更好地格式化 URL 以利用 QR 码的构造方式。
URL 中存储了不必要的数据。
URL 总体上可能要短得多。
让我们来看看这些,看看它们能带来什么不同。我们将忽略在真实和现有应用程序/基础设施的上下文中实际实施这些的现实,这可能会显着改变适当的技术决策。
更大的二维码
海报中的二维码很小。当以默认 A4 0打印时,每边只有约 5 厘米(2 英寸),这意味着大约不到总页面区域的5%是二维码,但这正是人们需要与之互动的地方。
让它更大会让扫描更容易,并且不会改变二维码本身的任何内容,因此肯定会继续使用现有的应用程序。我想新南威尔士州的大多数人现在都熟悉如何使用这些代码,因此可以不强调这些说明。
我对页面元素进行了一些非常快速的改组和大小调整,没有编辑或重排文本(只需删除代码1周围的蓝色框),并且绝对有可能使代码更大。如果应用更多的编辑肘部润滑脂,它可能会更大。
打印在A4纸上时,新版的代码是每边16厘米,大三倍多,所以大概可以从三倍远的地方扫描。它现在占用了大约 40% 的页面区域。
(发布后,有几个 人指出,在某些情况下,真正巨大的二维码似乎会在实践中造成扫描困难。人们需要在实践中实际测试设计以验证特定尺寸。)
更好的二维码
我们已经完成了使二维码变大的最简单步骤,现在让我们将整个海报中的二维码做得更好。这是我们将应用的更改顺序,从左到右,从上到下。代码变得更简单,具有更大的模块(小方块),因此变得更容易扫描。
我们将看到绿色的“短路径”二维码如何保留我们上面确定的所有有价值的属性,包括简单的离线登记支持。“删除名称”代码甚至更简单,如果我们很好地妥协离线签入,这是可能的。
更少的纠错
QR 码使用最高纠错 (EC) 级别:H。正如在QR 纠错帮助和阻碍扫描中所探讨的,有四个纠错级别,它们对应于可以损坏的模块数量仍然可以扫描 QR 码. 它们还会影响可以存储的数据量:
欧共体水平 | 最大伤害 | 数据存储(相对于 L) |
---|---|---|
高(高) | 30% | 43% |
Q(四分位数) | 25% | 57% |
M(中) | 15% | 79% |
L(低) | 7% | 100% |
我想大多数代码都被放置在相对非敌对的环境中(室内,或至少在掩护下),因此可以减少 EC 级别 H 的使用,或使其可配置。降低一级,到 Q,将版本从 16 减少到 13,使每个模块(小方块)更大——面积增加 17%——因此整个二维码更容易扫描。
进一步下降会使模块更大,尽管最大的胜利来自从 H 到 Q 的移动,并且每个较低级别的弹性都更小。
欧共体水平 | 版本 | 模块尺寸(相对于 H) | 与之前的对比 |
---|---|---|---|
H | 16 | —— | —— |
问 | 13 | +17% | +17% |
米 | 11 | +33% | +13% |
升 | 9 | +53% | +15% |
这也不会更改已编码数据的任何内容,因此应继续使用现有应用程序。
我们确实希望这些代码对损坏具有合理的弹性,所以让我们选择 Q。
网址的结构
我们已经完成了最简单的部分,现在我们需要真正考虑二维码中编码的数据。更少的数据意味着更小的版本,这意味着更大的模块,因此更容易扫描。此二维码存储一个 URL,其中包含一个大型 base64 JSON 片段。我们可以通过几种方式进行优化,其中一些似乎适用于现有应用程序,而另一些则不适用。我们可以独立查看 URL 的各个部分:
方案:
https://
域:
www.service.nsw.gov.au
路径:
campaign/service-nsw-mobile-app
查询:
data=eyJ0IjoiY292aWQxOV9idXNpbmVzcyIsImJpZCI6IjEyMTMyMSIsImJuYW1lIjoiVGVzdCBOU1cgR292ZXJubWVudCBRUiBjb2RlIiwiYmFkZHJlc3MiOiJCdXNpbmVzcyBhZGRyZXNzIGdvZXMgaGVyZSAifQ==
最简单的部分是方案,因为有两个选项https://
和老派http://
:我们可以保存一个字符,但似乎不值得放弃加密。让我们离开它,然后选择https://
。
更少的数据:删除不必要的信息
实际变化的最低悬而未决的结果是 4,查询。此查询当前是一个data
值为 base64 编码的 JSON value的单个参数eyJ0…fQ==
。JSON 包含一个baddress
字段......我在应用程序或网站中找不到任何显示此字段的地方,实际上删除它似乎可以正常工作。生成的编码 JSON 为eyJ0IjoiY292aWQxOV9idXNpbmVzcyIsImJpZCI6IjEyMTMyMSIsImJuYW1lIjoiVGVzdCBOU1cgR292ZXJubWVudCBRUiBjb2RlIn0=
104 个字符,低于 160 个字符。
JSON 值 | 网址长度 | Q版 |
---|---|---|
原配 baddress | 228 | 13 |
新无 baddress | 172 | 11 |
听起来不错。让我们选择删除该baddress
字段。
模式:上壳
二维码根据数据包含的字符以四种模式之一对数据进行编码:
模式 | 允许的字符 | 每个字符的位数 |
---|---|---|
数字 | 0123456789 | 3.33 |
字母数字 | 0–9, A–Z, 空格, $%*+-./: | 5.5 |
二进制 | 任何字节 | 8 |
汉子 | 移位 JIS X 0208 | 13 |
每个字符的位数越低越好:这意味着我们可以在给定的空间中容纳更多的字符。URL QR 码中的大多数数据将使用二进制模式,因为通常会有小写字母,但我们可以使用字母数字模式做得更好:URL 的许多组件都可以是大写字母,而不会导致问题或改变行为。比如域名是不区分大小写的,而且很多服务器对待路径也是不区分大小写的。Base64 编码区分大小写,所以我们不能大写。
幸运的是,二维码可以用不同的模式2对数据进行多段编码,所以我们仍然可以从中受益:第一部分可以用字母数字编码,而带有 base64 值的第二部分可以是二进制。
网址 | 与应用程序一起使用 | 升 | 问 |
---|---|---|---|
原来的:https://www.service.nsw.gov.au/campaign/service-nsw-mobile-app?data=eyJ… | 是的 | 8 | 11 |
大写域和方案:HTTPS://WWW.SERVICE.NSW.GOV.AU/campaign/service-nsw-mobile-app?data=eyJ… | 是的 | 8 | 11 |
只有数据小写:HTTPS://WWW.SERVICE.NSW.GOV.AU/CAMPAIGN/SERVICE-NSW-MOBILE-APP?DATA=eyJ… | 不 | 7 | 11 |
第二个选项 - 仅大写域和方案 - 就我们所得到的而言,仍然(似乎)与现有的应用程序安装一起工作。
该选项的大写不会对我们这里拥有的数据产生影响,尽管它确实减少了所需的总位数,因此对于某些名称/ID 恰好推送的企业来说可能会有所不同它们就在版本边界之上。
最后一个选项——大写除了 base64 值之外的所有内容——在我们选择的纠错级别 Q 上也没有太大区别,但在其他像 L 的情况下却是这样。
由于我们处于极限,我们现在进入了想象的世界,在那里官僚主义是组成的,现有用户无关紧要。所以让我们锁定最后一个。
更少的数据:更好的编码
我们的 URL 现在看起来像:HTTPS://WWW.SERVICE.NSW.GOV.AU/CAMPAIGN/SERVICE-NSW-MOBILE-APP?DATA=eyJ0IjoiY292aWQxOV9idXNpbmVzcyIsImJpZCI6IjEyMTMyMSIsImJuYW1lIjoiVGVzdCBOU1cgR292ZXJubWVudCBRUiBjb2RlIn0=
。
base64 JSON 值eyJ0…In0=
看起来仍然值得考虑:它现在包含的数据更少,但它仍然占用 QR 码中 70% 的存储空间(总共 1256 位中的 880 位)。它存储在?DATA=
查询参数中的 URL 中,它包含的数据是:
{ "t": "covid19_business", "bid": "121321", "bname": "Test NSW Government QR code", }
不幸的是,来自 JSON(所有{":,
s)的开销很大,然后来自 base64 的开销更大。
我们可以做得更好,因为我们有简单的文本数据和简单的值(纯字符串)。这意味着我们可以通过查询参数或直接在路径中直接传递 URL 中的值,这为我们节省了一点开销?N=…
。我们已经/C
在 URL 中获得了 指示签入的 ,所以我们可能可以删除"t": "covid19_business"
,我们这里的方案是非常手工制作的,所以我们可以尽可能地优化参数。
编码 | 长度 | 问 |
---|---|---|
原始,JSON + Base64:...?DATA=eyJ0… | 172 | 11 |
网址参数:...?T=COVID19_BUSINESS&BID=121321&BNAME=name… | 126 | 8 |
更好的 URL 参数:...?I=121321&N=name… | 101 | 7 |
路径中的 ID:.../121321&N=name… | 99 | 7 |
路径中的所有内容:.../121321/name… | 67 | 7 |
这有很大的不同。我们的网址是现在下降到97个字符(从原本228) HTTPS://WWW.SERVICE.NSW.GOV.AU/CAMPAIGN/SERVICE-NSW-MOBILE-APP/121321/Test+NSW+Government+QR+code
。
让我们锁定最后一个选项,选择在 path 中有效地编码事物。
看看那个二维码简单得多。
更少的数据:更好的路径
接下来,CAMPAIGN/SERVICE-NSW-MOBILE-APP
路径的初始组件相当长……我们真的需要拼出“广告系列”和“移动应用程序”吗?至少不是“手机应用”!
让我们把它剪下来。这里有两个不错的选择:根本没有路径,或者很短的路径。
小路 | 长度 | 问 |
---|---|---|
原来的 CAMPAIGN/SERVICE-NSW-MOBILE-APP | 97 | 7 |
C | 67 | 5 |
空的 | 65 | 5 |
这里没有太大区别,因此最好包含C
以区分链接何时用于签入。如果路径为空,则 URL 看起来像HTTPS://WWW.SERVICE.NSW.GOV.AU/121321/...
,这意味着首页HTTPS://WWW.SERVICE.NSW.GOV.AU
需要检测路径是否像签入 ID 并重定向到适当的页面(在 Web 浏览器中加载时),这听起来很烦人并且需要相对不寻常的代码。
让我们选择这个简短的单字符路径。
更少的数据:更好的域
正在使用的域很长:WWW.SERVICE.NSW.GOV.AU
. 我们绝对不需要全部拼写出来。这里有多种选择:当前 URL 的缩短,如Q.SERVICE.NSW.GOV.AU
或S.NSW.GOV.AU
;或者一些非常简短的东西,比如NSW.AU
(这个域不存在,但任何 6 个字符的域都是等价的)。最佳选择可能取决于相关组织的官僚作风和 dev/sys-ops 要求。
领域 | 长度 | 升 | 问 |
---|---|---|---|
原来的WWW.SERVICE.NSW.GOV.AU | 67 | 4 | 5 |
Q.SERVICE.NSW.GOV.AU | 65 | 4 | 5 |
S.NSW.GOV.AU | 57 | 3 | 5 |
NSW.AU | 51 | 3 | 4 |
这些选择中的大多数在 Q 级没有区别,但它们确实减少了整体数据(因此在某些情况下可能会有所不同)并减少 L 级的版本。让我们选择S.NSW.GOV.AU
,因为范围在GOV.AU
第二级域似乎更值得信赖:HTTPS://S.NSW.GOV.AU/C/121321/Test+NSW+Government+QR+code
.
这个 57 个字符的 URL 仍然包含与原始 228 个字符的 URL 相同的所有有用信息。以下是 JSON 片段中的四段数据:
"t": "covid19_business"
⇒/C/
在路径中"bid": "121321"
⇒ 第一个路径参数"bname": "Test NSW Government QR code"
⇒ 第二个路径参数"baddress": "…"
⇒ 删除,因为它没有被使用
最后两个二维码看起来很相似,因为它们都是第 5 版;模块的密度和大小没有改变,但它们的确切排列已经改变。
减少离线支持
当 URL 包含企业名称以启用离线签入3时,我们几乎处于极限。如果我们放弃对此进行编码的要求会怎样?例如,该应用程序可以说“您正在检查企业”而不是显示名称以供确认,甚至可以让应用程序存储自己的数据库,将 ID 映射到企业名称4。
如果我们这样做,URL 可以是 29 个字符:HTTPS://S.NSW.GOV.AU/C/121321
. 这适合第 2 版二维码!
(橙色站点上的@dhsysusbsjsi指出,通过一些进一步的调整,人们甚至可以进入版本 1,但这些确实需要进一步降低纠错,到 L 或 M。)
这是黑客攻击吗?更改会失去安全性吗?
没有。当前的新南威尔士州二维码本质上是不安全的,我们所经历的任何变化都没有使它们或多或少地安全。
有很多人拥有将它们分开并生成具有不同商业 ID、名称或地址值的新的技能。base64 编码不是加密,因为编码或解码不需要密钥/密码。Base64 是一种在 Internet 上存储和通信数据的非常常见的方式,以至于有些人甚至可能会立即将三个字符的前缀识别eyJ
为“这是 base64 的 JSON”。
使这些5安全的一种方法是对URL进行加密签名,添加额外的信息,这些信息是使用新南威尔士州服务局持有的密钥从数据中计算出来的。加载用于签入的 URL 时,应用程序会验证签名是否匹配。如果有人试图篡改数据,他们需要更新签名,但在不知道密钥的情况下,他们需要非常幸运的猜测。
例如,200 位BLS 签名可以提供足够的安全性。为了了解这可能带来的开销,我们可以假设我们以某种方式生成了这种大小的签名并将其添加到 URL(这不是真正的加密协议,不要相信我的话)。首先,将其编码为 61 位数字以受益于数字 QR 模式,然后将其添加为额外的查询参数…?…&S=16069…
。这确实使 URL 变长,因此需要更高的版本,但我们的优化为此腾出了空间,这意味着 QR 码仍然更容易扫描,同时具有更好的安全性:
二维码 | 未签名版本 | 签名版 |
---|---|---|
原来的 | 16 | 17 |
为应用程序优化 | 11 | 12 |
完全优化 | 5 | 7 |
其他州
澳大利亚的每个其他州都有类似的登记流程,包括海报上的应用程序和二维码。其中大多数使用比新南威尔士州更简单的二维码,但它们也做出了其他权衡:
南澳大利亚和维多利亚包括场地名称,因此也可能很好地支持离线签到。但是,SA 肯定需要互联网才能办理登机手续,我不确定维多利亚。
维多利亚州和西澳大利亚州的 QR 码似乎具有真正的安全性(例如,WA 使用JSON Web Token,其中包括加密签名,但有人指出,对称签名的选择使该值有问题)。
首都领地、昆士兰、北领地和塔斯马尼亚都拥有基本相同的应用程序和二维码,并使用高效的 URL(包含大量数字数据),但有一些看似不必要的冗余。
大多数州使用纠错级别 Q,但维多利亚州和西澳大利亚州将级别降低到 M:这两个州也拥有最长的 URL,与新南威尔士州的 URL 相似或更长,这可能并非巧合。
我们学到了什么?
在本文中,我们通过查看新南威尔士州使用的签到海报逐步完成了为现实世界优化 QR 码的过程。我们将这些海报变成了更容易使用的东西,并在此过程中涉及:
当前值机二维码的内容及其功能
二维码的工作原理(纠错、版本和编码模式)
优化存储在二维码中的数据的演练,在不影响功能的情况下从版本 16 移动到版本 5
这些二维码的安全性,观察如何提高安全性并让代码更容易扫描
我们没有考虑在现有应用程序和/或支持基础设施中实际实施这些的现实情况。适当的技术权衡可能会发生巨大变化。
转自:https://huonw.github.io/blog/2021/10/nsw-covid-qr/
本文为转载文章,版权归原作者所有,不代表本站立场和观点。
上一篇:如何快速学习新的编程语言和框架
下一篇:消耗性数字商品