一张二维码标签沾上了污渍,或者中间盖住了一小块,手机有时仍然能读出内容。直觉上,少了几块黑白格子,信息就应该缺一截。为什么它还有机会被完整读出来?答案藏在两个不同的问题里:读码器怎样找到这张码,以及它怎样修复读到的数据。 先说二维码为什么出现。二维码研发公司的官方历史记载,一维条形码逐渐普及时,用户希望存进更多信息,也希望编码汉字和假名。研发团队的目标不只是增加容量,还要让读取更快。一九九四年,二维码正式发布。名字里的两个英文字母,来自英文“快速响应”,表达的正是这个设计目标。它后来被汽车行业用于电子看板,帮助生产、运输等环节管理信息。今天常见的手机扫码,是这项技术发展出来的日常用途。 把一张普通二维码想成一块由许多小方格组成的黑白棋盘。其中三个角,各有一个显眼的、像方形靶心一样的标记。这三个标记首先帮助读码器定位二维码,判断它的朝向。你把纸转过一个角度,读码器仍有机会认出它,不必先把整张纸摆正。 这些方形标记也有讲究。沿着中心穿过去,黑白区域的宽度比例是一比一比三比一比一。官方历史说,团队调查了印刷品中各种图形的黑白比例,选择了一种不容易与周围图案混淆的比例。理解这个细节,不需要记住每一个数字;关键在于,二维码先用容易识别的结构告诉机器:信息在这里,应当按这个方向读。 不过,找到位置,只解决了第一步。真正解释部分污损仍能读取的,是纠错。生成二维码时,系统除了写入原本要保存的信息,还会加入额外的纠错信息。这家公司的官方资料说明,这里使用的是里德—所罗门纠错码。只要损伤没有超出可纠正的范围,读码器就能利用这些额外信息,恢复受损的数据。 可以借一个很简单的算术例子理解冗余:如果你同时知道两个数,以及它们的和,其中一个数看不清了,就有机会通过减法找回它。二维码实际采用的数学比这个例子复杂得多,并不是往图里再放一份完整的原文。但共同的思路是,预先存入一些有约束关系的信息,让后来出现的缺失或错误有机会被纠正。 二维码有四个纠错等级。按照官方表格,L 级大约百分之七,M 级大约百分之十五,Q 级大约百分之二十五,H 级大约百分之三十。这几个百分比最容易被讲错。它们表示的是相对于总码字的恢复能力。码字是一组八个二进制位,可以简单理解成编码数据的一小份单位。它不是二维码上单独一格,也不是整张图的面积单位。 所以,H 级大约百分之三十,并不意味着随便遮住三成面积,就一定能扫出来。实际损伤怎样影响编码数据、遮住了哪些结构,以及读码器能否取得清晰图像,都关系到最后结果。官方介绍也特别注明,数据是否能够恢复,取决于污损的实际情况。看到一张中间带图案的二维码能被读取,只能说明那张码在当时条件下成功了,不能由此推导出任何二维码都可以这样处理。 这里还有一项代价。更高的纠错等级需要更多纠错信息。同样的原始内容,可能需要更大的二维码版本来容纳;如果坚持使用同一版本,能够容纳的原始内容就会减少。若把更多小格子挤进同样大小的印刷区域,每个格子会变小,摄像头和印刷质量又会成为限制。纠错能力更高,不能抵消所有成像问题。 除了里面的格子,二维码四周的空白也有作用。官方要求普通二维码的四边各保留四个小格子宽的空白区,其中不要印其他内容。这块留白帮助读码器分清边界。把周围裁得太紧,或者让图案挤进留白,都是拿实际可读性冒险。定位标记、清楚的黑白差别、合适的格子大小,也需要一起保留。 因此,遇到扫不出的二维码,先清洁表面、减少反光,让画面对焦清楚,通常比猜测它还有多少纠错额度更实际。如果必须制作标签,应保持完整结构与留白,并在实际使用的尺寸、材质和设备上测试。官方常见问题说明明确提醒,覆盖插画或改变图案可能使读取变慢,甚至让很小的缺损也造成失败。 二维码被遮住一点还可能扫出来,是因为它把定位和纠错一起放进了设计里。那份余量是为了应对真实世界的污损,而不是给任意遮挡作保证。知道百分比衡量的究竟是什么,也就更容易理解:一张码偶尔被救回来,和一张码应当可靠地使用,是两回事。