使用方法
- 打开页面就有一组完整结果:种子 upc、数字系统符 0、数量 20,结果区已经列出 20 个 12 位码,不需要先填任何东西。
- 「随机种子」任意文字都行,同一个种子配上同一个数字系统符与数量,永远得到同一批码,方便贴进测试用例或工单后原样复现。
- 「数字系统符」默认 0,下拉框里每一项都标了含义:0、1、6、7、8 是普通商品,2、4 是店内码,3 是药品 NDC,5、9 是优惠券。
- 「生成数量」默认 20,可填 1 到 500。数量超过 12 时,下方对照表会只展开前 12 行,其余行靠「加载更多」展开。
- 点「立即生成」或改动任一项都会重算;结果区那一行写明本次的数字系统符、条数与校验方式,是当场算出来的。
- 结果区下面是纯号码列表,一行一个;「复制结果」复制的就是它,可以直接粘进表格或导入脚本。
- 下方对照表逐条拆出厂商码、商品码与校验位,默认显示 12 行;「导出 CSV」保存为带字节序标记的文件,「复制对照表」复制制表符分隔文本。
- 本页不联网、不写本地存储,刷新即回到默认示例;生成的号码只是样例,不能当作已注册的商品码使用。
这个UPC生成器能解决什么
做零售系统、仓储脚本或条码打印调试时,经常需要一批「长得像真码」的 UPC-A:12 位、最后一位必须通过校验、前 11 位的分段要说得清。随手敲 12 个数字很容易在扫码环节被判为非法,问题往往就出在校验位。这个UPC生成器把生成与校验绑在一起——先按结构取数,再用 mod 10 推出最后一位,因此每一条输出都是自洽的合法码。
第一类是调试与演示。接口联调、打印模板预览、库存表的样例数据,都需要一批能通过校验的号码,而不是随机十二位数字。本页一次最多给 500 条,并且按「种子推进」的方式生成,同一种子永远得到同一批,断言可以写死。
第二类是核对与教学。手上有一个现成的 12 位码,想知道它的校验位对不对,或者想搞明白为什么最后一位是那个数——对照表里奇位和、偶位和、总和、校验位四列摊开,把推导过程完整暴露,不用去翻规范原文。
边界必须说清:本页生成的号码是随机样例,进入真实流通前必须向 GS1 申请厂商代码,否则会与他人已注册的商品码冲突。页面在提示条里把这句话写死,是因为这条一旦被忽略,后果是整批商品贴错码。
结构、校验位与生成算法
UPC-A 一共 12 位,分四段:第 1 位是数字系统符(NSC),第 2 到 6 位是厂商代码,第 7 到 11 位是商品代码,第 12 位是校验位。前 11 位承载信息,第 12 位完全由前 11 位决定,本身不携带任何新信息。
校验位算法是本页的核心:把奇数位数字相加乘 3,加上偶数位数字之和,取总和的 mod 10,再用 (10 − 余数) % 10 得到校验位。这里的奇数位指第 1、3、5、7、9、11 位(按 1 起数,不含校验位本身),这是最容易记错的一处——按 0 起数会得到完全不同的结果。
由此可以得到一条常被忽略的结论:合法的 UPC-A 只有 10 的 11 次方种,而不是 10 的 12 次方。因为前 11 位一旦确定,校验位就唯一确定,所谓「随机生成 12 位」里真正随机的只有 11 位。本页也正是先取 11 位、再算第 12 位。
与 EAN-13 的关系可以这样理解:UPC-A 可以看成首位补 0 的 EAN-13。EAN-13 是 13 位、主要用于北美以外;扫描枪读到 UPC-A 时会把它当成前面补 0 的 EAN-13 来解码,这也是两种码能在同一套设备里共存的原因。
本页的生成算法是确定性的:数字系统符由下拉框给定,第 2 到 11 位各取 Math.floor(s / 2147483647 × 10) % 10,其中 s 按 s = (s × 1103515245 + 12345) & 0x7fffffff 推进;种子先按字符码累加再 & 0x7fffffff,所以字符串 upc 折成 328。第 12 位按上面的公式算出,不参与随机。
| 变量 | 含义 | 取值 | 影响 |
|---|---|---|---|
| nsc | 数字系统符 | 0 ~ 9 的单个数字 | 决定第 1 位与码的用途类别 |
| seed | 随机种子 | 任意字符串,字符码累加折成整数 | 决定第 2 到 11 位,同种子结果一致 |
| cnt | 生成数量 | 1 ~ 500 的整数 | 只决定输出条数,不影响单条结构 |
| odd | 奇位和 | 第 1、3、5、7、9、11 位之和 | 乘 3 后参与校验,权重要高于偶位 |
| cd | 校验位 | (10 − (奇位和×3 + 偶位和) % 10) % 10 | 填在第 12 位,由前 11 位唯一决定 |
完整示例
默认示例的种子是 upc(折 328)、数字系统符 0、数量 20。第一条前 11 位是 05456942239,奇数位 0、4、6、4、2、9 之和为 25,乘 3 得 75;偶数位 5、5、9、2、3 之和为 24;总和 99,99 % 10 = 9,校验位 = (10 − 9) % 10 = 1,于是完整码是 054569422391。后面十九条共用同一条序列继续推进,不是各自重开。
种子 upc(折 328)· 数字系统符 0 · 数量 20 第 1 条 前 11 位 05456942239 奇位和 25×3 = 75 偶位和 24 总 99 校验位 1 → 054569422391 第 2 条 前 11 位 01843131286 奇位和 22×3 = 66 偶位和 15 总 81 校验位 9 → 018431312869 第 3 条 前 11 位 03099428901 奇位和 21×3 = 63 偶位和 24 总 87 校验位 3 → 030994289013 第 4 条 前 11 位 04478481690 奇位和 26×3 = 78 偶位和 25 总 103 校验位 7 → 044784816907 第 5 条 前 11 位 01345188437 奇位和 27×3 = 81 偶位和 17 总 98 校验位 2 → 013451884372
把种子改成 20261025(折 402),其余参数不动,前五条变成 059821894527、065152568259、008126731242、018853785234、080010617405——第一条的厂商码是 59821、商品码是 89452、校验位 7。把数字系统符改成 3(药品 NDC)再生成,第 1 位会整批变成 3,校验位随之全部重算。
生成结果与数字系统符对照表
下表逐条拆开默认这一批结果:序号、完整 12 位码、数字系统符、厂商代码、商品代码、校验位。共 20 行,默认显示 12 行,点工具区的「加载更多」看余下 8 行。
| 序号 | 完整 12 位码 | 数字系统符 | 厂商代码 | 商品代码 | 校验位 |
|---|---|---|---|---|---|
| 1 | 054569422391 | 0 | 54569 | 42239 | 1 |
| 2 | 018431312869 | 0 | 18431 | 31286 | 9 |
| 3 | 030994289013 | 0 | 30994 | 28901 | 3 |
| 4 | 044784816907 | 0 | 44784 | 81690 | 7 |
| 5 | 013451884372 | 0 | 13451 | 88437 | 2 |
| 6 | 024304743647 | 0 | 24304 | 74364 | 7 |
| 7 | 015651076793 | 0 | 15651 | 07679 | 3 |
| 8 | 047312645826 | 0 | 47312 | 64582 | 6 |
| 9 | 054938498620 | 0 | 54938 | 49862 | 0 |
| 10 | 060759610158 | 0 | 60759 | 61015 | 8 |
| 11 | 064191755736 | 0 | 64191 | 75573 | 6 |
| 12 | 025288357080 | 0 | 25288 | 35708 | 0 |
| 13 | 060977705124 | 0 | 60977 | 70512 | 4 |
| 14 | 076367059609 | 0 | 76367 | 05960 | 9 |
| 15 | 003367646720 | 0 | 03367 | 64672 | 0 |
| 16 | 059945035820 | 0 | 59945 | 03582 | 0 |
| 17 | 050457991420 | 0 | 50457 | 99142 | 0 |
| 18 | 012956943980 | 0 | 12956 | 94398 | 0 |
| 19 | 015310588278 | 0 | 15310 | 58827 | 8 |
| 20 | 053719949931 | 0 | 53719 | 94993 | 1 |
第二张表是数字系统符的含义,十档全列。选哪一位不只是一个数字,它决定了这条码在零售体系里被当成什么类别来处理。
| 数字系统符 | 含义 | 典型用途 |
|---|---|---|
| 0 | 普通商品 | 常规零售商品,本页默认 |
| 1 | 普通商品 | 常规零售商品 |
| 2 | 店内码 | 生鲜称重等店内核价 |
| 3 | 药品 NDC | 药品与国家药品编码衔接 |
| 4 | 店内码 | 生鲜称重等店内核价 |
| 5 | 优惠券 | 券类凭证 |
| 6 | 普通商品 | 常规零售商品 |
| 7 | 普通商品 | 常规零售商品 |
| 8 | 普通商品 | 常规零售商品 |
| 9 | 优惠券 | 券类凭证 |
第三张表是校验位的四个精核算例,可与上面的推导逐字对照:总和为 0 时校验位也是 0,这是最容易怀疑自己算错的一档。
| 前 11 位 | 奇位和×3 | 偶位和 | 总和 | 校验位 | 完整 12 位码 |
|---|---|---|---|---|---|
| 03600029145 | 42 | 16 | 58 | 2 | 036000291452 |
| 01234567890 | 60 | 25 | 85 | 5 | 012345678905 |
| 00000000000 | 0 | 0 | 0 | 0 | 000000000000 |
| 72527273070 | 78 | 16 | 94 | 6 | 725272730706 |
结果边界与错误提示
- 「生成数量」不是 1 到 500 的整数时,提示写明当前填了什么、允许范围是 1 到 500;填小数或文字同样按这条报错,不做四舍五入。
- 种子被清空时自动填回 upc;种子里可以包含中文、空格与符号,字符码累加后一律折成 31 位整数。
- 数字系统符只接受下拉框里的 0 到 9,不提供其它取值;改成非数字的选择不会进入计算,页面按 0 处理并给出提示。
- 校验位一律按 (10 − 总和 % 10) % 10 计算,总和为 0 时校验位为 0,不会出现 10 这个非法数字。
- 厂商代码与商品代码可能出现前导 0(例如 03367、05960),复制与导出都按文本处理,不会被当成数字丢掉前导 0。
- 数量超过 12 条时对照表只展开前 12 行,其余行由「加载更多」控制;导出 CSV 与复制对照表始终包含全部行,不受展开状态影响。
- 页面明确提示:生成的号码是随机样例,进入真实流通前必须向 GS1 申请厂商代码,否则会与他人已注册的商品码冲突。
- 本页不上传任何输入,也不写本地存储;导出的对照表 CSV 带字节序标记,复制结果为纯文本。
常见问题
校验位到底怎么算?
把第 1、3、5、7、9、11 位相加乘 3,加上第 2、4、6、8、10 位之和,得到总和后取 mod 10,再用 (10 − 余数) % 10 得到校验位。注意奇数位是按 1 起数、且不含第 12 位,按 0 起数会算错。
为什么说合法 UPC-A 只有 10 的 11 次方种?
因为第 12 位完全由前 11 位决定,本身不携带新信息。前 11 位每一位有 10 种取法,所以合法组合是 10 的 11 次方种,而不是 12 位数字看起来的 10 的 12 次方。
数字系统符选 3 会怎样?
第 1 位整批变成 3,这一位是药品 NDC 类别。校验位会跟着重算,因为第 1 位是奇数位、权重是乘 3 的,改一位就会让后面所有的校验位发生变化。
生成的码能直接印在商品上吗?
不能。本页生成的是随机样例,厂商代码并没有在 GS1 注册,直接印制会与他人已注册的商品码冲突。真实流通前必须向 GS1 申请厂商代码,再自行编排商品代码。
厂商码出现前导 0 会有问题吗?
不会。UPC-A 是定长文本而不是整数,第 2 到 6 位允许全 0 或前导 0。本页在输出、复制与导出时都按字符串处理,前导 0 会被完整保留。
UPC-A 和 EAN-13 是什么关系?
UPC-A 可以看成首位补 0 的 EAN-13。EAN-13 有 13 位、主要用于北美以外;扫描枪读到 UPC-A 时会当成前面补 0 的 EAN-13 来解码,因此两者能在同一套设备里共存。
换个种子结果会完全不同吗?
会。种子按字符码累加折成整数后驱动整条序列,种子差一个字符,第 2 位就会改变,后面全部随之变化。种子 20261025 与 upc 的两批结果没有任何公共前缀。
导出的 CSV 带字节序标记吗?
带。对照表 CSV 导出时写入 UTF-8 字节序标记,Excel 双击不乱码;「复制对照表」是制表符分隔文本,粘进表格软件会自动分列,「复制结果」则是纯号码列表。
相关工具
- 条形码生成器:生成可直接渲染的条码图形。
- ISBN生成器:生成带校验位的国际标准书号。
- 虚拟信用卡号生成器:生成通过 Luhn 校验的测试卡号。
- 统一社会信用代码校验:校验 18 位信用代码的校验位。
- 宾果卡号生成器:按宾果规则生成随机卡面号码。