使用方法
- 三个数字框分别是生成数量、随机种子与固定前缀,都写了 min、max、step。默认 5、20261107、0,表示用固定种子产出 5 个全随机前缀的 EAN-13。改完任意一个直接按 Enter 重算。
- 多行文本框是待编码商品行:每行写一条商品名称,脚本按顺序给每行赋一个完整 EAN-13,并把前缀、权重和、校验位、完整码逐项列出。它默认已经直出五行商品;多行输入约定 Ctrl/Cmd + Enter 触发。
- 结果区带 role="alert":五张卡片给出批量生成个数、赋码商品行数、13 位码总数、首个权重和与首个校验位,下面
<pre>逐行打印生成器的递推式、每个码的前 12 位与校验位推导,以及两个标准样例的核对结果。 - 点「复制结果」取走整段快照;「导出对照表 CSV」下载带 BOM 的表格;「复制对照表 TSV」把 16 行前缀按制表符复制。对照表默认只显示 12 行,点「加载更多」展开其余 4 行。
- 想复现同一批码,记下种子即可;想换一批,改种子或固定前缀。点「载入示例」会把三个数字框与五行商品一起还原并重新实算。
生成与校验全在浏览器内完成,不发起网络请求、不写 Cookie、不碰 localStorage,也不向任何 GS1 机构查询前缀归属。
这个工具能解决什么问题
第一,批量产出「能被扫描逻辑接受」的 EAN-13 用于测试与占位。做收银系统联调、打印模板排版、电商导入样例时,需要一批格式合法的条码,但不需要真的去申请厂商代码;本页用确定性随机数填满前 12 位,再补出校验位,得到的码在校验算法层面是自洽的。
第二,把「随机」的边界讲清楚。随机EAN条码生成器这一名称里的「随机」只修饰前 12 位:最后一位是前面 12 位的函数,没有任何随机性。把 13 位全随机是最常见的翻车点,本页把加权和与校验位逐行打印出来,让你一眼看出第 13 位是怎么被算出来的,而不是又抽了一个数。
第三,让结果可复现。线性同余生成器用固定种子递推,同一种子、同一固定前缀、同一组商品行永远得到同一批码,方便把「某次测试用的码」精确复现给同事;这与一次性随机数不同,也不依赖浏览器时间或系统熵。
边界同样要说明:本页只生成数字串,不画条码图形、不分配真实 GS1 厂商代码、不保证全球唯一、不判断某个前缀是否已被注册,也不联网查重。旧占位脚本曾把本页做成从词表里随机拼单词的通用生成器,与条码毫无关系,本页不沿用那套逻辑。
计算原理与校验位公式
前 12 位。默认全部随机。脚本用固定种子的线性同余递推 s = (Math.imul(s, 1103515245) + 12345) & 0x7fffffff,再按 Math.floor(s / 2147483647 * len) 取一位数字,逐位拼满 12 位;若固定前缀大于 0,则前 3 位取该前缀的零填充三位,其余 9 位仍由递推式产出。种子相同则序列相同,这是可复现的来源。
加权和。把前 12 位从左往右编号,第 1、3、5……位(奇数位)乘 1,第 2、4、6……位(偶数位)乘 3,全部相加得 sum。标准样例 400638133393 的权重和是 89,590123412345 的权重和是 83,两个数都由脚本对前缀逐位算出,不是查表得来的。
校验位。第 13 位 = (10 − sum % 10) % 10,也就是把加权和补到最近的 10 的倍数所需的差值;当 sum 本身已是 10 的倍数时结果为 0,所以要再取一次模,不能写成简单的 10 − sum % 10。完整码 = 前 12 位 + 校验位。400638133393 补出 1 得到 4006381333931,590123412345 补出 7 得到 5901234123457。
本页真正要讲透的是:第 13 位是校验位,不是随机数。EAN-13 的 13 位里,前 12 位是承载信息的主体,可以按业务规则随机或顺序分配;最后一位却完全由前 12 位决定,它的熵是 0,只是前面 12 位的函数。扫描枪或收银系统读码时会自己按奇数位乘 1、偶数位乘 3 重算一遍补数,若末位对不上就直接判为无效码;所以如果把 13 位全都随机生成,绝大多数情况下根本扫不出来——随机 ≠ 全位随机。也正因为如此,校验位能挡住一位录错与相邻位交换,却不能防伪:算法是公开的,任何人都能给任意 12 位补出正确末位。本页坚持先用固定种子的递推式产出 12 位,再按加权和补出第 13 位,并把权重和与计算过程逐行打印,让你能核对每一位是怎么来的;把第 13 位也交给随机数,等于把整个码的自检能力作废。
完整示例(标准样例实算)
标准样例一:前 12 位 400638133393。页面脚本逐位加权实算得权重和 = …,校验位 = …,完整 EAN-13 = …。
标准样例二:前 12 位 590123412345。脚本实算得校验位 = …,完整 EAN-13 = …。这两个结果都由同一个加权和函数算出,源码里没有写死;对照表前两行正是它们。
批量生成的那几行则按另一种方式呈现:结果区会列出每个码的前 12 位、权重和、校验位与完整码,并把递推式写在最前面。改种子或固定前缀,整批码会变,但两个标准样例的核对结果不变,因为它们的前缀是固定的输入。
对照表怎么读
工具区下方那张表由脚本对 16 个前 12 位前缀逐个调用加权和与校验位函数生成:列是前缀、权重和、校验位、完整 EAN-13,后三列全是算出来的。前两行是标准样例,其余 14 个前缀由固定种子 20261107 的线性同余递推式产出,因此整张表本身也是可复现的。
默认显示 12 行,点「加载更多」展开其余 4 行;「导出对照表 CSV」给带 BOM 的文件,「复制对照表 TSV」给制表符文本,都包含展开后的全部行。读表时把「权重和」与「校验位」两列对着看:权重和末位是 9,校验位就是 1;末位是 3,校验位就是 7,补数关系一目了然。
结果边界与舍入规则
- 三个数字框的非法值。空值、非数字、越界或带小数各有指名到具体输入框与当前值的提示;脚本不会用「取不到就当 0」兜底,也不会把生成数量 0 静默改成 1。
- 固定前缀的范围。只接受 0 到 999 的整数,0 表示 12 位全随机;大于 0 时零填充成三位锁在前缀开头,其余 9 位随机。填 1000 或负数会明确报错,而不是截断成三位。
- 商品行整框为空。会中止并提示恢复默认五行,绝不把空清单静默当成 0 行后照样报「生成成功」。行内文本本身不解析,只按顺序赋码。
- 种子与复现。种子相同、固定前缀相同、商品行相同,输出就逐字相同;这是线性同余递推的性质,不是缓存。改种子即换一整批,不需要清缓存或刷新页面。
- 不四舍五入。权重和、校验位、每一位数字都是整数,整条链路没有小数可舍;校验位公式里的两次取模保证结果为 0 到 9 的整数,不会出现 10。
- 合法性的边界。本页保证的是「校验位自洽」,不保证 GS1 前缀已注册、不保证全球唯一、不画条码图形、不联网查重;要正式商用请走正规编码申请流程。
- 本地性。只有位运算、整数乘法与取模,没有 fetch、没有表单提交、没有第三方脚本,也不写 Cookie 或 localStorage。
常见问题
第 13 位为什么不能也随机?
因为它是前面 12 位的函数:奇数位乘 1、偶数位乘 3 求和,再补到 10 的倍数。扫描设备会重算这一位,末位对不上就判无效。把 13 位全随机,绝大多数码都扫不出来,随机不等于全位随机。
校验位的公式为什么要取两次模?
校验位 = (10 − sum % 10) % 10。若 sum 已经是 10 的倍数,10 − 0 = 10 不是一位数字,再对 10 取模才得到 0。漏掉外层取模会在权重和恰为整十时算出非法的两位末位。
400638133393 的校验位怎么算出 1?
奇数位乘 1、偶数位乘 3 求和得 89;89 % 10 = 9,(10 − 9) % 10 = 1,完整码 4006381333931。本页由脚本逐位实算,权重和与结果都可在对照表第一行核对。
590123412345 为什么补出 7?
同一套加权口径求和得 83;83 % 10 = 3,(10 − 3) % 10 = 7,完整码 5901234123457。两个标准样例的存在就是让你能用已知答案反查脚本有没有算错。
固定种子有什么用?
线性同余递推由种子完全决定,同一种子、同一固定前缀、同一组商品行会产出逐字相同的一批码,方便把测试数据精确复现给同事。它与依赖系统时间或熵的一次性随机数不同。
固定前缀填了以后还是「前 12 位随机」吗?
默认 0 时 12 位全随机;填了大于 0 的三位值后,前 3 位被锁定、其余 9 位仍随机。这是可选的占位功能,用来模拟厂商前缀;无论哪种情况,第 13 位始终由加权和算出,不参与随机。
生成的码能直接商用吗?
不能。本页只保证校验位自洽,不分配真实 GS1 厂商代码、不保证全球唯一、不联网查重,也不画条码图形。做联调、排版、导入样例足够,正式商用要走正规编码申请流程。
生成的码会上传吗?
不会。全流程只有位运算、整数乘法与取模,没有网络请求、没有表单提交、没有第三方脚本,也不写 Cookie 或 localStorage。关掉标签页,整批码随页面一起消失。
相关工具
- 随机数生成器:需要一次性随机整数时用它,注意它给的是离散数,不会替你补 EAN 校验位。
- 密码生成器:需要不可预测的兑换凭证时用它,条码与权益码对「可预测性」的要求正好相反。
- base64编码工具:把一批生成好的码编码成文本便于存档传输,编码不改变校验位,也不改变码本身。