Seth Larson 做了一个很小的纸笔实验:在一张带 10×10 网格和 2×10 辅助网格的便签纸上,手绘出一个能被手机识别的二维码。

这个二维码不是 Micro QR,而是普通 QR Code 的 Version 1。它的尺寸是 21×21 个模块,也就是最小规格里的常见起点。

我更在意的不是“人手也能画二维码”这件事,而是它暴露了二维码真正依赖什么:不是黑白块像不像,而是每个模块在不在该在的位置上。

21×21 模块先卡住了纸和内容

Version 1 的 21×21 模块,听起来很小。落到便签纸上,就不轻松。

Larson 手里的网格只有 10×10。要画 21×21,他必须把格子拆半,还要利用边距。纸张、留白、模块大小,马上从“美观问题”变成“能不能识别”的问题。

内容也有边界。

他最初发现,小写完整 URL https://sethmlarson.dev 放不进这个 Version 1 码,于是改用 sethmlarson.dev。后来有读者指出,如果把 URL 改成全大写,QR Code 可以走 alphanumeric 字符集,HTTPS://SETHMLARSON.DEV 也能放进去。

这里的重点是:二维码容量不是一句“能放多少字节”就能讲完。它取决于版本、纠错等级和编码模式。

变量Larson 的处理影响
QR 规格普通 QR Code Version 1固定为 21×21 模块
纸面网格10×10 网格拆半,并借用边距决定模块是否能画准
内容选择先用域名,后确认全大写 HTTPS URL 可行编码模式会改变容量上限
参考生成用 Python 的 qrcode避免人工重新排布数据
命令细节echo -n避免尾随换行被编码进去

这对技术读者很有用。以后看二维码容量,不要只问“这个 URL 多长”。要看它被当作 byte mode 还是 alphanumeric mode,也要看纠错等级。

对做手工名片、贴纸、网格画的人,也有一个直接动作:先用工具生成参考码,再照着模块画。不要凭视觉补块。二维码不是马赛克画。

手绘能成,靠定位图案和纠错

Larson 的绘制顺序很关键。

他先画三个角上的定位图案,再补时序线,最后填数据模块。定位图案告诉扫描器“这里有二维码”。时序线帮助扫描器确认网格节奏。数据区才是具体内容。

这也是很多人误解二维码的地方。

它不是把黑白块随便凑到一起。结构区错了,扫描器可能连入口都找不到。数据区错一点,反而还有机会被纠错拉回来。

Larson 在绘制过程中逐步测试。画到一定阶段后,手机已经开始把这块图案当作二维码处理。最终即使有一处数据错误,在最低纠错等级 L 下仍然可以识别。

这里能看出二维码和一维条码的差别。一维条码主要沿一个方向读取宽窄线条。二维码把定位、格式、数据和纠错都塞进二维网格。Denso Wave 1994 年推出 QR Code 时,服务的是制造和物流里的快速识别;今天它能被手绘复现,靠的仍是这套工程取舍。

规矩越清楚,容错才有意义。

真正的限制在纸面误差

实验后半段最有意思的限制,不在算法,而在纸。

纸张卷曲会影响近距离扫描。Larson 把纸压平后更容易识别;把二维码挂在显示器上,效果反而更好。原因并不神秘:扫描器需要看到稳定的边界、足够的对比,以及相对平整的模块排列。

这对两类人影响不同。

对研究二维码原理的技术读者,这个实验适合当一张“最小可观察样本”。你可以从 Version 1、纠错等级、编码模式、格式信息、静区这些变量入手,看哪些是硬条件,哪些是可容忍误差。

对喜欢纸笔实验和网格艺术的创作者,动作更具体:

  • 保留二维码四周静区,不要让装饰贴太近;
  • 用深色笔和浅色纸,别让对比度变低;
  • 控制墨迹扩散,模块边界要清楚;
  • 画完先压平再扫,不要拿卷曲纸面硬试;
  • 如果要放进完整 URL,优先检查编码模式,而不是直接换更大的码。

接下来最该看的,也不是“能不能画更复杂”。更现实的变量是误差边界:粗笔会不会糊住模块,彩色墨水会不会降低对比,纸面弯折到什么程度会失败,提高纠错等级会不会换来更大图案。

目前能确认的是,手绘二维码可行。但它不是玄学,也不是运气。它只是把标准留出的余量,用一支笔和一张纸显了形。