QR Codes: How They Work and How to Use Them Safely
二维码原理与安全使用
A QR code is a two-dimensional barcode: a square grid of black and white "modules" that encodes a short string. Invented in 1994 by the Japanese company Denso Wave to track car parts on assembly lines, QR (Quick Response) codes have since become the default way to share a URL, a Wi-Fi password, or a payment address from a piece of paper to a phone. Their appeal is mechanical — they survive damage, scan from any angle, and hold a surprising amount of data.
二维码是一种二维条码:一个由黑白"模块"组成的方阵,用来编码一段较短的字符串。它由日本 Denso Wave 公司于 1994 年发明,原本用于汽车装配线上追踪零件。如今,二维码已经成为从纸面分享网址、Wi-Fi 密码或收款地址到手机的标准方式。它的优势在于物理特性 —— 抗损坏、全方向可读、容量远超普通条码。
Anatomy of a QR code
二维码的内部结构
Every QR code is a square of "modules" — the individual black or white squares you see when you zoom in. The smallest possible code is 21 × 21 modules (called "Version 1"), and the largest defined is 177 × 177 (Version 40), with each step up adding 4 modules to each side. The same code is laid out in concentric regions, each with a specific job:
每个二维码都是一个由"模块"组成的方阵 —— 放大后看到的那些黑白小方格。最小的二维码是 21×21 模块(称为"版本 1"),最大的标准版本是 177×177(版本 40),每升一级每边加 4 个模块。同一张二维码由若干同心区域组成,每个区域各司其职:
- Finder patterns — the three big nested squares in three corners. They let the scanner detect the code and figure out its orientation, so you can scan it rotated or mirrored.
- 定位图案 —— 三个角上的大嵌套方块。它们让扫描器检测到二维码并判断方向,因此可以旋转或镜像扫描。
- Alignment patterns — smaller nested squares in the bottom-right region of larger codes, used to correct for distortion when the code is printed on a curved surface.
- 校正图案 —— 大尺寸二维码右下角区域的较小嵌套方块,用于在曲面印刷时校正畸变。
- Timing patterns — alternating black/white strips that run between the finder patterns. They give the scanner a reference for module size and grid alignment.
- 时序图案 —— 在三个定位图案之间交替排列的黑白条带。它为扫描器提供模块尺寸和网格对齐的参考。
- Format and version information — small encoded regions near the finder patterns that tell the scanner the error-correction level, mask pattern, and version number.
- 格式与版本信息 —— 定位图案附近的小块编码区域,告知扫描器纠错等级、掩码图案和版本号。
- Data and error-correction modules — the rest of the grid, which holds the actual payload and the Reed–Solomon redundancy that lets the code survive damage.
- 数据与纠错模块 —— 网格的其余部分,用于存放真正的载荷,以及让二维码能"扛损伤"的 Reed–Solomon 冗余数据。
The four error-correction levels
四级纠错等级
Every QR code carries extra "error-correction" data so the scanner can reconstruct the message even when part of the code is dirty, scratched, or covered. There are four levels, and the trade-off is simple: more redundancy means more resilience, but less space for the actual payload.
每个二维码都带有冗余纠错数据,即使部分图案被污损、划伤或遮挡,扫描器也能恢复出原信息。一共四个等级,权衡关系很简单:冗余越多越抗造,但留给真正载荷的空间就越少。
- L (Low) — recovers ~7% of data loss. Best for clean environments where you want maximum capacity.
- L(低) —— 约可恢复 7% 的数据丢失。适合环境干净、追求最大容量的场景。
- M (Medium) — ~15% recovery. The default for most general-purpose codes.
- M(中) —— 约 15% 恢复能力。绝大多数通用场景的默认选择。
- Q (Quartile) — ~25% recovery. Good for codes that might be smudged or partially obscured.
- Q(较高) —— 约 25% 恢复能力。适合可能被弄脏或部分遮挡的二维码。
- H (High) — ~30% recovery. Used when a logo sits in the middle of the code, or when the code is printed in a harsh environment.
- H(高) —— 约 30% 恢复能力。常用于在二维码中央放 logo,或打印环境较为恶劣的情况。
This is why a QR code with a small logo in the middle still scans cleanly — the logo is just a block of "missing" modules, and the error-correction layer fills in around it. The Reed–Solomon algorithm that powers this is the same family used in CDs, Blu-ray discs, and satellite communication.
所以在二维码中央放一个小 logo 仍然能扫 —— 那块"缺失"的模块被纠错层自动补上了。支撑这种能力的 Reed–Solomon 算法与 CD、蓝光光盘和卫星通信使用的是同一家族。
Mask patterns and data encoding
掩码图案与数据编码
A naive encoding of a long bit string into a grid would produce some patterns that scanners find very hard to read — large solid blocks, isolated single pixels, or accidental alignment-like shapes. To avoid that, the encoder XORs the data with one of eight predefined "mask patterns" and picks the one that produces the most scannable result. The chosen mask is recorded in the format information, so the scanner knows how to undo it.
如果直接把长位串放进网格,会出现一些扫描器非常难识别的图案 —— 整片纯色、孤立的单像素,或巧合地"长得像"定位图案。为避免这种情况,编码器会用 8 种预定义"掩码图案"之一对数据做 XOR 异或,并挑出扫起来最顺眼的那一种。选中的掩码会被写进格式信息,扫描器据此还原数据。
The payload itself can be encoded in four modes, picked automatically based on the input to maximize density:
载荷本身可以用四种模式之一编码,系统会根据输入自动选择密度最高的方式:
- Numeric — digits only, encoded at 10 bits per 3 digits. Up to 7,089 characters at Version 40 / L.
- 数字 —— 仅数字,每 3 位占 10 比特。版本 40 / L 级下最多 7,089 个字符。
- Alphanumeric — uppercase letters, digits, and a small set of symbols. Up to 4,296 characters.
- 字母数字 —— 大写字母、数字加少量符号。最多 4,296 个字符。
- Byte — raw 8-bit data (UTF-8 for text). Up to 2,953 bytes.
- 字节 —— 原始 8 位数据(文本按 UTF-8 处理)。最多 2,953 字节。
- Kanji — Shift JIS, one character per 13 bits. Up to 1,817 characters.
- 汉字 —— Shift JIS 编码,每字符 13 比特。最多 1,817 个字符。
A useful and often-overlooked feature is structured append: a single message can be split across up to 16 codes, with a header that lets the scanner reassemble them in the right order. This is how large vCards or long URLs can be broken into smaller, individually scannable codes on poster-sized prints.
一个常被忽略但很有用的特性是结构化追加:同一条消息可以拆成最多 16 个二维码,并通过头部信息让扫描器按正确顺序重组。这正是把很长的 vCard 或网址拆成多个小二维码印在大幅海报上的实现方式。
Dynamic vs static codes
动态码与静态码
A static QR code encodes the destination directly in the pattern itself. Once printed, it cannot be changed — if the URL breaks, the code is dead. A dynamic QR code points to a short URL managed by a service, which then 301-redirects to whatever target the operator has configured. The operator can update the destination, see how many people scanned the code, and A/B-test different landing pages.
静态二维码把目标地址直接编码进图案本身。一旦印出来就无法更改 —— 链接失效,二维码就废了。动态二维码指向一个由服务商管理的短链,再由短链 301 跳转到实际目标。运营者可以随时修改目标链接、查看扫码次数,并对落地页做 A/B 测试。
Dynamic codes are great for marketing, but they have two downsides. First, they create a single point of failure: if the redirect service shuts down, every printed code stops working. Second, because the destination is hidden, a malicious actor can paste their own dynamic code over a legitimate one and you would not know where you were about to go until you scanned. Always preview the URL your scanner is about to open.
动态码非常适合营销,但有两个缺点。第一,它构成了单点故障:跳转服务一停,所有已印刷的二维码都失效。第二,因为目标被隐藏,恶意者可以把合法二维码换成自己的动态码,直到你真的扫了你才知道要去哪。扫码前一定要先看清预览里的链接。
Security risks: quishing and how to stay safe
安全风险:二维码钓鱼与防范
Phishing delivered by QR code has earned the nickname "quishing". A sticker over a parking meter, a flyer in a coffee shop, a PDF attachment in an email that asks you to "scan to verify your account" — all can point to a credential-harvesting page that looks identical to the real one. The same risks apply as for any link-based phishing, with one extra wrinkle: on a phone, you are more likely to be signed in to sensitive apps, more likely to grant permissions, and less likely to be paying close attention to a URL bar.
用二维码投递的钓鱼攻击有个昵称叫"quishing"。停车场计费表上的贴纸、咖啡馆里的传单、邮件附件中"扫码验证账号"的 PDF —— 都可以指向一个与真实页面一模一样的凭据收集页。这种风险与普通链接钓鱼一样,只是多了一个特点:在手机上,你更可能已经登录各种敏感应用,更可能随手授权,也更少仔细看地址栏。
A few habits cut the risk dramatically:
几个习惯能大幅降低风险:
- Let your phone's camera show you the URL before opening it. If the URL is shortened, a random string, or a domain you do not recognize, do not open it.
- 让手机相机在跳转前先显示 URL。如果是短链、随机串,或你完全不认识的域名,不要点开。
- Be suspicious of codes that arrive by email, especially when they claim urgency — "scan now or your account will be locked".
- 对邮件里发来的二维码保持警惕,尤其是带"立即扫码,否则账号将被锁定"这类催促口吻的。
- If a code is on a physical surface, check whether it looks like a sticker placed over an original code.
- 如果是贴在实物表面的二维码,先观察它是否像一张覆盖在原码上的贴纸。
- For payments, only scan codes that you can independently verify came from the recipient.
- 涉及支付时,只扫你通过独立渠道确认由对方发出的码。
- Use a scanner that lets you preview and confirm before opening the link, rather than one that auto-opens.
- 选择支持"预览并确认"再打开链接的扫描器,而不是直接自动跳转的。
Try the tools
试试这些工具
Create your own static QR code with the QR code generator. Pick an error-correction level that suits your use case, and export the result as a PNG ready for print.
用 二维码生成器 创建你自己的静态二维码。选择合适的纠错等级,导出为可印刷的 PNG 即可使用。