把一长串二进制代码装进个方块,让手机扫描器一眼就能读到,这在原理上看起来挺玄乎。
实际上就是一场关于“空间压缩”和“位置记忆”的猫鼠游戏。想象一下,你手里拿着一堆散乱的小石子,想打包一箱快递。传统做法是把它们规整码放在托盘上,每个位置都固定不动,拿的时候得费力翻找,要么得做长鼻子把它们一个个挑出来塞进那个硬壳箱子里。
这就好比直接拼那些无意义的 0 和 1,信息量大,但存空间浪费,扫描的时候也得费脑筋去匹配。 而二维码技术的核心,就是发明白一种叫“二维矩阵”的摆法。它不要求石子按顺序码放,也不做长鼻子分类,而是把所有信息均匀地铺在平面上,形成一个规整的网格状结构。
这种结构最大的益处就是,扫描头不需求去猜那个石子在哪,只需求用一束光扫那会儿,光线照到黑块上,再反射到相机里,相机就能直接对像素进行计算,算出它归于哪一行、哪一列。
这就好比把一堆散乱的鹅卵石堆成了规整的方块,扫读起来快又准,并且不管你如何拿那个方块,反正都是整规整齐的。 这就引出了一套巧妙的“位置记忆法”。对于每一个黑块,二维码不直接记录它到底存了啥,而是记下来:它左边挨着几个白块,右边跟着几个白块,上面顶着一个白块,下面压着一个白块。
这就相当于把石子的位置和属性打包在一起,印在了它周围。当你把这些带有位置信息的黑块排成矩阵,再把这些矩阵交叉重叠、拼接起来时,整个二维码就形成立体了。别看黑块本身就代表了信息,可是这些黑块的位置关系本身,就是另一种形式的编码。
这种编码方式贼高效,出于只有黑块才占地方(白的是背景,没人看),所有的实际数据都挤在那些黑块上。 再说说为啥手机能看懂。手机扫描器本质上是一个微型投影仪,它发出的光被黑块反射回来,出于白块是空的,故此反射回来的光线极少。相机捕捉到的就是这些黑块反射回来的光斑。一旦相机成功获取了这些黑块对应的反射图像,就能够通过算法分析出每个黑块的像素值,进而还原出它周围那无数个“位置记忆”数据,还原出整个的矩阵,最终把矩阵解出来,把原本乱糟糟的 0 和 1 拼出来。
这就好比你在乱丢的鹅卵石堆里,每天花点工夫把它们按顺序码放好,放在一个标好编号的小盒子里,然后每天出门看一眼盒子,就能知道里面装的是啥了,并且盒子能够装得比散乱的石子多得多。 为了让大家更直观地理解这种“位置记忆”的妙用,不妨看看一个常见的例子。假设你要在二维码里存一个“张三”的名字。按照传统的思路,你可能得先做一个表格,第一行是“姓名”,第二行是“王五”,第三行是“李四”,第四行是“赵六”,第五行是“张三”。每一个名字都输在一个固定的格子里。
这种结构最大的难题就是,每次阅读都得把格子翻开。而二维码里存“张三”的方式不一样,它可能只在那一行的特定列里,要么在某个特定的角上。
哪怕二维码被折叠得乱七八糟,手机也能通过重新扫描,重新定位那行、那列,直接找到那个存着“张三”的黑块。
这就解释了为啥二维码折叠包、卷起来都能扫出来,出于关键的“位置”信息保存有了方块内部,而不是保存有方块本身。 实际上,二维码的构造过程有点像乐高积木。先把一个个带有位置指令的黑块拼成矩阵,再把矩阵像搭积木一样一层层叠加。当两个矩阵重叠时,编号会形成变化,这就是所谓的“校验码”。
要是扫描头扫到了校验码那块,它就知道这一层积木是不是对的,是不是被压歪了。
要是不对,校验码就会告诉你:“哎呀,这堆积木离位了,请重新扫一遍。”这种自我纠错的本事,让二维码在长期使用、反复折叠的情况下依然能保持准率。 最终想到的是,这种设计在传输效率上简直是把成本转嫁给了存介质。
一般/平平文本文件,字数越多,体积越大。而二维码,它只负责把数据“打包”,不负责“张罗”。数据一旦到了二维码,它就是一堆黑块,不管有没有被张罗,扫出来还是那串数据,只是多了几个用来定位的黑块罢了。
这就好比把一堆散乱的鱼干放在一个袋子里,袋子的体积挺小,但鱼干的数量能够无限多。
要是你需求把鱼干存到硬盘里,你是要占硬盘空间;要是你是想存大量条鱼干,你只需求一个袋子,袋子再大也没关系。二维码就是那个袋子,而数据是那些鱼,鱼的数量多到没个边,袋子却小得挺。
这种以空间换信息密度的策略,正是二维码能在手机上留下的痕迹,也是它能在各种怪形状下依然能工作的根本缘由。