校验位的存在意义:扫描不只是看线条
当你在超市收银台扫描一个商品条码时,扫描枪读取的不仅仅是表面的黑白线条——它还会在毫秒级内自动执行一次数学验证。条码的最后一位数字并不是商品信息的一部分,而是一个由算法计算出的校验位(Check Digit)。它的唯一功能是确认前面所有数字是否被正确扫描,防止因墨迹模糊、标签磨损或光线干扰导致的读取错误。
如果校验位算出的值与条码最后一位不匹配,扫描器会立刻判定"读取无效"并要求重新扫描——这是零售供应链中最基础也是最重要的数据完整性保障之一。
模 10 算法(Luhn 变体):完整推演

EAN-13 和 UPC-A 使用的校验位算法本质上是同一种加权模 10 校验(Weighted Modulo-10 Checksum)。以下用 EAN-13 为例进行完整推演。
示例:计算 EAN-13 码 690123456789? 的校验位
前 12 位已知数字为:6 9 0 1 2 3 4 5 6 7 8 9
第一步:分配权重
从左到右,依次给每一位分配交替的权重系数 1 和 3:
| 位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 数字 | 6 | 9 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 权重 | 1 | 3 | 1 | 3 | 1 | 3 | 1 | 3 | 1 | 3 | 1 | 3 |
第二步:逐位相乘并求和
每位数字 × 对应权重,然后全部加起来:
(6×1) + (9×3) + (0×1) + (1×3) + (2×1) + (3×3) + (4×1) + (5×3) + (6×1) + (7×3) + (8×1) + (9×3)
= 6 + 27 + 0 + 3 + 2 + 9 + 4 + 15 + 6 + 21 + 8 + 27 = 128
第三步:对 10 取模
128 mod 10 = 8(128 除以 10 余 8)
第四步:用 10 减去余数
10 - 8 = 2
如果结果等于 10,则校验位取 0;否则结果即为校验位。
最终结果:校验位 = 2,完整的 EAN-13 码为 6901234567892
UPC-A 的校验位计算
UPC-A 的校验位算法与 EAN-13完全相同,只是作用于 11 位数字(总长 12 位,最后 1 位为校验位)。权重交替规则也一样:第 1 位权重 3,第 2 位权重 1,第 3 位权重 3……(注意 UPC-A 的首位权重是 3,与 EAN-13 相反)。
从数学上看,UPC-A 码 012345678905 等价于 EAN-13 码 0012345678905——在前面补一个 0 就变成了标准的 13 位 EAN 码,校验位保持不变。
为什么权重是 1 和 3?

这种特殊的 1-3 交替权重方案具有以下数学优势:
- 能检测到100% 的单位替换错误(任意单个数字被误读为另一个数字)
- 能检测到约 90% 的相邻位转置错误(两个相邻数字被交换)——这是条码扫描中最常见的第二种错误类型
如果使用简单的等权累加(所有权重都是 1),则完全无法检测转置错误——"12" 和 "21" 的等权和相同。
在 illi.io 上验证你的条码
如果你手边有一个条码需要验证校验位是否正确,最快捷的方式是在 illi.io 的条码生成器中输入你的编号并生成条码——系统会自动计算并附加正确的校验位。如果你手动输入的校验位与系统计算的不一致,就说明原始条码存在印刷错误或读取误差。
常见错误与排查
- 校验位不一致:最常见的原因是录入时把 "6" 误看成 "8"、"1" 误看成 "7" 等视觉混淆。请逐位核对原始数字
- 位数不对:EAN-13 必须恰好 13 位,UPC-A 必须恰好 12 位。多一位或少一位都会导致校验失败
- 权重方向搞反:EAN-13 第一位的权重是 1(不是 3)。UPC-A 第一位的权重是 3(不是 1)。方向搞反会得到错误的校验位