跳到主要内容

条码最后那一位数字,是怎么算出来的

EAN-13、UPC-A、EAN-8 的校验位究竟怎么算、为什么能抓住输错的号码,从原理到实操,附真实计算示例。

发布于
#条码 #EAN #UPC #校验位 #零售

条码最后那一位数字,是怎么算出来的

超市收银台偶尔响起一声短促的报错提示音。不是扫描头出了问题,而是收银员手输了一串商品号,最后一位敲错了。条码校验位把这个错误拦了下来,赶在系统里登记一条无效编号之前。

GS1 在 1977 年发布 EAN-13 标准时就内置了这个机制。根据 GS1 通用规范(GS1 General Specifications,第 7.9 节),Mod-10 校验算法能 100% 捕获单个数字错误,并能发现大多数相邻两位互换的情形,而这两类恰好是人工键入时最常出现的失误。

算法核心:从右往左,交替乘 3 和 1

规则只有一句话:把主体各位数字从右往左依次交替乘以 3 和 1,把所有乘积相加,让这个总和成为 10 的倍数所需的最小补数,就是校验位。

权重为什么选 3 和 1?因为两者不同。如果两个相邻位置的权重一样,那互换这两个数字对加权和毫无影响,校验就失去了意义。3 和 1 的差值足够大,互换后总和几乎总会改变,从而触发失败判定。

手算一遍:以实际 EAN-13 为例

我拿一瓶常见洗洁精的条码做演示。包装上印的完整 EAN-13 是:

4 0 0 6 3 8 1 3 3 3 9 3 1

最后一位 1 是校验位,前 12 位主体是 400638133393

EAN / UPC 条码校验位计算器打开,把主体 400638133393 粘进"计算"框,工具显示加权过程和最终的校验位。我对照着手算了一遍,从右往左的 12 位依次是:

| 位置(从右) | 数字 | 权重 | 乘积 | |---|---|---|---| | 1 | 3 | 3 | 9 | | 2 | 9 | 1 | 9 | | 3 | 3 | 3 | 9 | | 4 | 3 | 1 | 3 | | 5 | 3 | 3 | 9 | | 6 | 1 | 1 | 1 | | 7 | 8 | 3 | 24 | | 8 | 3 | 1 | 3 | | 9 | 6 | 3 | 18 | | 10 | 0 | 1 | 0 | | 11 | 0 | 3 | 0 | | 12 | 4 | 1 | 4 |

乘积之和 = 9+9+9+3+9+1+24+3+18+0+0+4 = 89

下一个 10 的倍数是 90,补数 = 90 - 89 = 1

工具给出的结果和手算吻合:校验位 1,完整 EAN-13 4006381333931

现在我故意把主体最后一位改成 8,输入 400638133398,工具立刻提示:验证失败,正确校验位是 1,而不是 8。一个数字之差,算法就能发现。

三种码制,同一套公式

EAN-13(13 位,国际零售)、UPC-A(12 位,北美主流)、EAN-8(8 位,小包装)用的是同一套 Mod-10 算法,区别只在主体长度:

  • 12 位主体 → 算出 EAN-13 的校验位
  • 11 位主体 → 算出 UPC-A 的校验位
  • 7 位主体 → 算出 EAN-8 的校验位

EAN / UPC 条码校验位计算器会根据输入位数自动识别码制,不需要手动选。

还有一个常被忽视的事实:UPC-A 就是 EAN-13 前面补了一个 0,两者校验位完全相同。北美供应商发来 11 位主体时,在前面加 0 凑成 12 位,重算一遍校验位,结果不变,这本身就是一次格式一致性的自洽验证。

两个实际使用场景

场景一:印刷前补齐条码

向 GS1 拿到前缀、分配完产品序号之后,手头是 12 位 GTIN 主体,标签图稿需要的是完整 13 位号码。把主体粘进工具,读出校验位,填回设计文件里的条码字段,条码字体就能渲染出可扫描的图形。这一位填错,意味着整批标签报废。

我之前帮一个做出口的朋友核查过一批标签文件,他们的操作流程是设计师手动在 Excel 里计算校验位,用的公式串错了权重顺序(从左往右数而不是从右往左),结果 8 位 EAN-8 全部算错,12 位 EAN-13 却因为偶数长度碰巧算对了一半。当时用这个工具逐一比对,几秒钟就把出错的那批挑出来,重新补算了正确校验位。

场景二:商品数据上传前批验

一张几千行 EAN 的商品表格即将上传到电商平台,一个错位就让一条商品被退回。常见的错误是从 PDF 复制粘贴时截掉了最后一位,生成的号码只有 12 位,校验位对不上。把可疑号码挨个过一遍工具,"失败"或"长度不符"立刻出现,比肉眼逐行检查快得多。

和其他校验算法的关系

EAN/UPC 用的是 GS1 版 Mod-10,和信用卡、部分证件号码使用的标准 Luhn 算法有细微差别,主要是权重的起始端和双倍减 9 的步骤不同。如果你的场景涉及银行卡号或身份识别码,可以试试 Luhn 算法验证器,它针对标准 Luhn 做了专门处理。

如果你不只是算校验位,还需要生成带条纹图案的可打印条码,可以直接用 条码生成器,支持 EAN-13、EAN-8、UPC-A、Code-128 等格式,生成即可下载或复制 SVG。

最容易踩的三个坑

  1. 把完整码粘进计算框:计算模式需要的是不含校验位的主体。粘进 13 位完整码,工具会当作 13 位主体去算"第 14 位校验位",结果毫无意义。完整码要放进验证框,主体才放进计算框。
  1. 从左往右数位置:权重 3/1 必须从最右边那位主体数字起算,往左交替下去。方向搞反,偶数位和奇数位对调,算出的校验位看起来是个正常数字,却是错的。
  1. 把通过当成真实:校验位只证明号码格式自洽,不证明这个 GTIN 已在 GS1 注册、对应真实商品。自己随手编一串数字,凑对最后一位同样能通过。通过 = 格式合法,不等于来源可信。

Made by Toolora · Updated 2026-06-10