
「条码是怎么工作的」是一个搜索量很大、答案很稳定的问题——稳定到几乎所有答案都是一段文字配一张静态图。静态图有说不清的事:EAN-13 的第 13 位数字其实不占用任何独立的图案,它藏在前六位的奇偶性里;Code 128 的校验值不是一个数字,而是一个完整的 11 模块字符;QR Code 的定位图形为什么长成三个角上的同心方块而第四个角没有。条码结构图解(英文名 Online Barcode Structure Diagram)把这些做成可交互的:悬停任意区域,看它占几个模块、起什么作用、缺了它会发生什么;输入任意内容,实时看它变成模块序列。
在线演示
条码结构图解(英文名 Online Barcode Structure Diagram):覆盖 EAN-13、Code 128、Code 39、ITF-14 和 QR Code 五种符号。页面自包含,没有 CDN 和构建步骤,键盘 Tab 也能遍历所有区域。
配合本文验证时可以这样走一遍:切到 EAN-13,悬停最左边的保护条看它为什么是 3 个模块;再悬停校验位,对照页面上的加权算式手算一遍;最后切到 QR Code,输入一段文字看版本和纠错等级如何改变分块布局。
关键要点
- 五种符号、一套渲染器:编码器返回同一形状的数据(模块序列 + 结构分组),
app.js从不硬编码任何模块数,全部问编码器要。 - ROLES 是与码制无关的词汇表(静区、保护条、起始符、数据、校验、终止符……),一种角色一种颜色,全页通用——「青色是保护条」在五种码里都成立。
- 页面说明由编码结果生成而非转录:每步算式、每个图案都从编码器输出读回,两者不可能各自漂移。
- 编码器经过三层验证:QR 按 ISO/IEC 18004 测试向量并与 python-qrcode 比对 160 种版本/纠错组合;一维码与 bwip-js 和公开符号表交叉核对;页面本身有无头浏览器全量巡检。
- 验证过程发现了参考库自己的问题:bwip-js 的 ITF 编码会改写数字内容,某些 EAN-13 载荷的校验位与 GS1 加权规则算出的不一致。
悬停能读到什么
每个区域都回答三个问题:这是什么(角色和一句话说明)、它占多少模块、如果它缺失或错位会破坏什么。以 EAN-13 为例:
| 区域 | 模块数 | 缺了会怎样 |
|---|---|---|
| 静区 | 各 9 | 读取器找不到符号起点 |
| 起始符 | 3 | 无法确定解码起点 |
| 左侧数据字符 | 6 × 7 | 丢失前六位数据 |
| 校验位 | 7 | 无法检测读取错误 |
| 终止符 | 3 | 无法确认符号结束 |
细节都在面板里:每个数据字符的 7 模块图案并排展示,校验位算式带着你输入的数字一步步算给你看,QR Code 的分块布局按版本和纠错等级实时重排。对 EAN-13,悬停左侧数据字符时还会展示奇偶表——那是最多被静态图漏掉的事实。
说明是生成的,不是抄的
这个页面最不一样的设计在于:解释文字不是从规范书里抄过来贴在图旁边的,而是从编码器的返回值里读出来的。编码器返回的不只是黑白模块序列,还有每个结构分组拥有哪些模块:
// 编码器返回同一形状:模块 + 结构分组 + 角色
{
modules: [1,0,1, /* ... */],
groups: [
{ role: "guard", start: 3, length: 3, title: "左侧保护条", /* ... */ },
{ role: "data", start: 7, length: 42, /* ... */ },
{ role: "check", start: 43, length: 7, /* ... */ }
]
}
app.js 因此不需要知道「EAN-13 校验位在第 43 到 49 模块」这类事实——它只画编码器给的东西。编码器错了,页面会明显地错,而不是错得悄无声息。这个性质让页面和编码器可以被同一套测试看住。
交叉验证时发现的三个事实
页面自带的一维编码器与 bwip-js 做了逐模块交叉核对,结果里三条值得记录:
- bwip-js 的
interleaved2of5会改写数字内容:给它 6 位数字,返回的符号实际编码了 4 位;14 位进来 8 位出去。符号本身合法,但不是你给的那个值,所以不能作为 GS1 ITF-14 的参照。本页面的 ITF 改为按公开的宽元素位置表独立验证——那是真实解码器使用的同一张表。 - bwip-js 在某些 EAN-13 载荷上算出不同的校验位:对
400638133393它要 1,而 GS1 加权规则的两种等价写法(从左 3,1,3… 或从右 1,3,1…)都得到 7,两种写法在偶数长度载荷上完全一致。模块比对只在不争议的码上运行,分歧被写成独立断言,防止将来被悄悄抹掉。 - 两个编码器为
ABC123456789选了不同的 Code 128 码集:都是合法的——规范并不规定选择算法——页面编码器的选择短一个符号字符。测试断言的是真正重要的性质(切换发生在哪、是否真的省了),而不是逐模块比对。
这三条都写进了验证脚本,所以它们不是「注意事项」,而是被测试固定住的事实。
边界
这是一个解释工具,不是认证编码器。EAN/UPC 附加码、Code 128 的 GS1 应用标识符功能字符、Code 39 全 ASCII 转义、QR 的数字/字母数字/字节之外的模式,都不在范围内。要看懂结构,它够了;要生成贴到商品上的标签,用在线条码与二维码生成器这类正式工具;要识别真实世界的条码,用在线条码扫描器。