如何用你的双眼读出二维码里的信息!

Made in love by Piko and blinry for 37C3


您想过二维码是如何工作的吗?你来对地方了!这是我们为 37C3 研讨会编写的互动式解释,但您也可以自行使用。您将学到:

目录

  1. 二维码剖析
  2. 掩码信息
  3. 编码信息
  4. 读取顺序
  5. 长度解码
  6. 内容解码
  7. 祝贺!

选择您的 QR 码

在开始之前,我们需要一个二维码!您有三种选择。首先,你可以输入任何文字,然后它就会更新下面解释的 QR 代码:

其次,您可以使用摄像头扫描任何现有的二维码,学习如何读取二维码:

第三,你可以使用随机英语单词!单词不会显示出来,这样你就可以用它来进行练习:

二维码剖析

这是您选中的 QR 码:

码的大小为 21×21 个模块(QR 码的像素名称)。

二维码有不同的尺寸,称为版本。最小的版本是 21×21 个模块,之后每增加一个版本,尺寸就增加 4 个模块!

下面是不同的部分:

定位码

它们有助于扫描器首先识别 QR 码。

隔离码

定位图案周围的空行,读取内容时一定要跳过它们。

对齐码

此二维码为版本 1,因此没有任何对齐码(这是帮助扫描器正确读取二维码的附加图案)。

计时码

两个始终交替排列的黑白模块--这是帮助扫描器正确读取二维码的另一种方法。

格式信息

这决定了掩码图案和纠错级别。有一个垂直版本:

还有一条水平版本。请注意,定时码隔断了两条线!

这是所有区域合在一起

没有突出显示的都是实际内容!

其它区域

还有一个区域没有在这里显示:静区是二维码周围的白色边框。它可以帮助扫描仪识别 QR 码的开始和结束位置。

掩码

为了避免大块的黑色或白色模块,二维码使用了掩码。有八种不同的选择。

这里指定了掩码模式:

黑色模块表示 1,白色方框表示 0。 在这种情况下,掩码模式由以下位组成 它们是二进制数 110。 它们与十进制数 6 相对应。

每种类型都有一个预定义的模式。为了更好地记住这些模式,可以使用下面的情景介绍。

掩码模式情景


看,你违法了。我真的很抱歉,我看到你的未来是黑色的 ,你将在栅栏之后:

但后来,事情发生了,一个故事展开了。就像这样,黑色从左到右移动:
于是,发生了什么?首先 ,你会穿上陈旧的条纹囚服
但你并没有失去希望彩虹让你坚持了斗志。

你在监狱的时间已经过半(对称密码: ),你开始有自己的爱好:
独处时 ,你画画,比如,画 例如埃舍尔(M.C. Escher)的《蜥蜴》
或者你用双眼观看 其他囚犯下棋
但时间流逝 你开始制定越狱计划:你将用斧头砍出一条出路。
最后 你设法逃了出来!这是你在监狱中的终点线,所以你会得到一面方格旗
现在,一切都是光明 和快乐,就像一张鲜花盛开的墙纸

在我们的案例中,模式 就是那个看起来像黑白彩虹的一部分

如果在二维码的数据部分重复这一模式,就会得到以下结果:

对于掩码中的每个黑色模块,您都要翻转二维码中的模块!接下来的步骤将告诉你如何操作。我们准备了一份 DIY 手册,其中包含所有掩码类型的速查表!你可以把它折叠成一个小册子,就像这样

编码模式

让我们开始解码内容!首先,我们需要知道内容的编码。该信息总是显示在右下角。

但是,请记住你首先要应用掩码!让我们来看看我们的小窍门吧。

让我们把这两个方框 XOR 在一起:

XOR =

同样,每种模式都有不同的编码模式。

数字
字母
Byte字节
ECI (扩展解释器)
汉字

对于我们的代码,编码模式是字节 Byte(4),因此我们可以继续!

读取顺序

内容从右下角开始。您向上走,在两列之间走之字形,然后在下一列向左走之字形。始终跳过所有特殊区域!

字节

前四位是编码模式。对于 ASCII 编码模式,接下来的八位指定内容长度。之后,每八位就是一个内容字节。


同样,我们也要应用掩码:

XOR =

长度解码

这是(未屏蔽unmasked)长度信息:

这些是比特位: 00001100


这些比特位以十进制表示: 12

该值是内容的总长度,以字节为单位!

内容解码

最后,我们就可以开始解码二维码的内容了!

这是第一个(未屏蔽)字节:

这些是比特位: 01001000


这些位以十六进制表示: 0x48


这就是相应的 ASCII 字符: H

这是第二个(未屏蔽)字节:

这些是比特位01100101


这些位以十六进制表示:0x65


这就是相应的 ASCII 字符:e

......等等!剩下的字节供您练习。当读取的字符数达到之前长度字段所指示的字符数时,就可以停止了。

ASCII 字符表

您可以使用此表将十六进制数字转换为 ASCII 字符!如果你是这样的人,也可以试着记住表格中的部分内容:小写字母以 0x61 的 "a "开头,以 0x7A 的 "z "结尾。中间的字母你可以数一数。

…0 …1 …2 …3 …4 …5 …6 …7 …8 …9 …A …B …C …D …E …F
0x2… !"#$%&'()*+,-./
0x3… 0123456789:;<=>?
0x4… @ABCDEFGHIJKLMNO
0x5… PQRSTUVWXYZ[\]^_
0x6… `abcdefghijklmno
0x7… pqrstuvwxyz{|}~DEL

纠错

那么,剩下的都是内容吗?不完全是!还有纠错功能,用于确保即使二维码的某些部分损坏、模糊或缺失,仍能被读取。纠错是由一些复杂的数学运算生成的,我们在这里不关心它,只关心如何读。

祝贺!

这应该就是你手动解码简单二维码所需的一切。现在,您可以按顶部的 "随机码 "按钮来练习简短的英语单词,或者去大街上找一个 QR 码,用 "扫描 "按钮来扫描它!

Found a bug? Feature request?

You can find the source code on Codeberg. We'd be especially happy about PRs that explain how UTF-8 encoding modes work! webhek.