条形码生成器

用浏览器自带的 Canvas 手写 Code 128:起始符、数据符、模 103 校验位、停止符逐条绘制,左右自动留出 10 个模块的静区,并实时告诉你模块数与画布尺寸。

页面打开时会自动生成一次:内容 LQ20261001、码集 B、模块宽度 2 px、高度 80 px,数据区 145 个模块,加左右各 10 个模块静区后画布宽 330 px。若这里一直显示这段文字,说明浏览器把 JavaScript 关掉了。

提示:在内容输入框里直接按 Enter 就会重新生成;画布不做设备像素比缩放,一个模块严格等于 X 个物理像素,这样导出的 PNG 放大后边缘仍是整数像素。

使用方法

  1. 在「条码内容」里填要编码的字符串,默认值是 LQ20261001。可填 ASCII 32–126 的可打印字符,长度 1~40 个——不是只能填数字。
  2. 「编码方式」默认「自动」。规则只有一条:内容是纯数字、位数 ≥ 4 且位数为偶数时改用码集 C,否则用码集 B。想固定行为就手动选「固定码集 B」或「固定码集 C」。默认值 LQ20261001 以字母开头,所以走码集 B。
  3. 「模块宽度 X」默认 2 px,这是 Code 128 标准里所说的 X 尺寸——最小条宽。「条码高度」默认 80 px。这两个值只影响画布尺寸,不影响编码内容。
  4. 点「生成条形码」,或在内容框里直接按 Enter。画布按「起始符 → 数据符 → 校验符 → 停止符」的顺序从左到右逐条绘制,左右各留 10 个模块静区。
  5. 点「下载 PNG」存图,点「复制编码参数」把码集、数值序列、加权和、校验位、模块数一起带走。页面下方的 Code 128 编码表默认显示 12 行,可以「加载更多」翻到全部 107 行,也能「导出 CSV」或「复制对照表」。

这个条形码生成器能解决什么问题

一是自己造标签。固定资产贴纸、样品袋编号、档案盒脊标、设备台账条码这类内部用途,不需要购买标签软件:把编号填进来,用条码打印机打出来就行。本页直接给 X 尺寸和总宽度,方便你先算好标签纸的宽度再排版。

二是打印前预检。很多"扫不出来"的条码不是内容错,而是尺寸错:模块宽度太窄、静区被裁掉、画布被缩放成非整数像素。本页把模块数、静区宽度和画布像素尺寸都显示出来,替换标签模板前就能判断会不会扫不动。

三是对账与教学。校验位是 Code 128 最容易出错的一环。页面把加权和与模 103 的结果都列出来,你可以拿它和标签软件、和硬件扫描枪手册上的算例逐位对照。

四是批号与串号。序号里既有字母又有数字时用码集 B,纯数字批号用码集 C,同样长度的内容宽度能省三分之一,小标签上更好排。

本页不做这些事:不生成 EAN-13、UPC-A、ITF-14 这类固定长度的零售码(它们的位数、校验规则都和 Code 128 不同);不生成二维码;也不识别条码——要读图请用页面底部的「条形码读取上传」。

生成原理:107 个模块图案、四个起始停止符与模 103 加权校验

Code 128 的图形是一串宽度值,不是一串字符。标准里一共定义了 107 个符号(值 0~106),每个符号由 3 条黑条和 3 条空白交替组成,宽度值只有 1、2、3、4 四档,加起来恒等于 11 个模块。唯一例外是值 106 的停止符,它是 7 段共 13 个模块,图案固定为 2331112。本页把这张表写成一个字符串常量,第 v 个符号的图案就是 PAT.substr(v * 6, 6),例如值 0 是 212222、值 103 是 211412。表中 106 个常规符号的宽度和全部等于 11、107 个图案互不重复,这两条是判断表格有没有抄错的自检手段。

三个起始符都以 211 开头。起始码 A / B / C 的图案分别是 211412、211214、211232,读码器正是靠这三位来判定条码从哪一侧开始、用哪张字符表。停止符 106 用 2331112,是全部 107 个符号里唯一的 13 模块符号,读码器见到它就收尾。因此一条条码的总模块数 = 11 × 符号个数 + 13,符号个数包含起始符、每个数据符、校验符。

校验位的算法是"位置加权求和再取模"。把起始符的值记为 V₀、第一个数据符记为 V₁,依此类推,则校验位 CS = (V₀ + Σ i × Vᵢ) mod 103,i 从 1 开始递增。注意权重是序号而不是位置索引,起始符的权重恰好是 1,所以直接把它当作累加初值即可。以默认值 LQ20261001 为例:起始符 104,字符 L、Q、2、0、2、6、1、0、0、1 在码集 B 里的值分别是 44、49、18、16、18、22、17、16、16、17,加权和 = 104 + 1×44 + 2×49 + 3×18 + 4×16 + 5×18 + 6×22 + 7×17 + 8×16 + 9×16 + 10×17 = 1147,1147 mod 103 = 14,所以校验符就是值 14(图案 122231)。数值序列连起来是 104 44 49 18 16 18 22 17 16 16 17 14,共 12 个符号,总模块数 11 × 12 + 13 = 145。

码集 B 的值来自 ASCII。码集 B 覆盖 ASCII 32~127 共 96 个字符,映射规则是"码值 = 字符码点 − 32",所以大写 L(76)对应 44、大写 Q(81)对应 49。本页只接受 ASCII 32~126,把 127(DEL)排除在外,因为它在文本框里看不见。码集 A 覆盖 ASCII 0~95(含 32 个控制符),码集 C 覆盖 00~99 共 100 组数字对。

码集 C 的意义是压缩数字。同样编码 20261001,走码集 B 是 1 个起始符 + 8 个数据符 + 1 个校验符 = 10 个符号、123 个模块;走码集 C 是起始符 105,后面接 20、26、10、01 四个数字对和校验位 5,共 6 个符号、79 个模块,窄了 35.77%(79 ÷ 123)。这就是"自动"模式对纯数字内容改走码集 C 的理由:位数越多省得越多,12 位数字能省 39.52%。

静区是标准要求,不是留白习惯。ISO/IEC 15417 规定 Code 128 两侧各留至少 10 个模块宽度的空白区(通常记为 10X),用来让扫描枪找到条码边界。本页固定按 10X 计算并直接画进画布,所以画布总宽 = (模块数 + 20) × X。默认参数下就是 (145 + 20) × 2 = 330 px。

完整示例(数值由本页编码器逐项复算)

示例条件与页面打开时的默认值完全一致:内容 LQ20261001、编码方式自动、模块宽度 X = 2 px、高度 80 px、显示可读文字。

把内容换成 20261001(8 位纯数字),自动模式切到码集 C:序列变成 105 20 26 10 01 05,加权和 211,mod 103 = 5,共 6 个符号、79 个模块,X = 2 时画布总宽只有 198 px。同一串数字 Code B 要 123 个模块,Code C 只要 79 个,节省 35.77%。下表对比几个常见长度(X 固定为 2 px,含静区):

内容字符数命中的码集符号数数据区模块画布总宽(含静区)
LQ2026100110B12145330 px
202610018(纯数字偶数位)C679198 px
12345678901212(纯数字偶数位)C8101242 px
A1B346132 px
40 个字符的编号40B42475990 px

把 X 从 2 px 调大画布会等比变宽:同样是 145 个模块,X = 1 时 145 px,X = 3 时 435 px,X = 6 时 870 px。"条码太长排不下"通常靠缩短内容解决,因为 X 调小有下限。

输入范围、编码表与尺寸对照

下面这张表就是编码器实际使用的 Code 128 图案表,值与图案一一对应。值 0~105 的每个符号都是 6 段、合计 11 个模块,只有值 106 的停止符是 7 段 13 个模块(2331112)。表格默认只渲染前 12 行,点「加载更多」每次追加 12 行,直到全部 107 行;「导出 CSV」导出完整表(带 BOM,Excel 打开中文不乱码),「复制对照表」把当前显示的行按制表符分隔复制到剪贴板。

值码集 A码集 B码集 C模块图案
0空格空格00212222
1!!01222122
2""02222221
3##03121223
4$$04121322
5%%05131222
6&&06122213
7''07122312
8((08132212
9))09221213
10**10221312
11++11231212

已显示 12 / 107 行

三个控件各自的取值范围如下,超出范围会直接给出提示而不是静默取默认值:

控件允许范围默认值越界时的行为
条码内容1~40 个 ASCII 32–126 字符LQ20261001空值、超长、含中文或控制符都会报错并指出第几个字符
编码方式自动 / 固定 B / 固定 C自动固定 C 遇到非偶数位纯数字时提示改回自动
模块宽度 X1~6 的整数 px2小数、空值、0、−1、7 一律拒绝
条码高度30~200 的整数 px80同上,并提示下限 30 px 的原因

结果边界、舍入与打印尺寸

常见问题

「自动」模式到底什么时候切到码集 C?

只有一个条件:内容全部是数字、长度 ≥ 4、长度为偶数。三条同时满足才用码集 C,否则用码集 B。所以 20261001(8 位)走 C,2026100(7 位)走 B,LQ20261001 走 B。判断标准是整串,不是"遇到数字就切"。

校验位算出来是 14,我自己能核对吗?

能。把起始符的值当作第 0 项,然后从第 1 个数据符开始按序号加权:104 + 1×44 + 2×49 + 3×18 + 4×16 + 5×18 + 6×22 + 7×17 + 8×16 + 9×16 + 10×17 = 1147,1147 ÷ 103 = 11 余 14。页面统计条里同时显示加权和与校验位,改一个字符数字就会跟着变,可以拿来验证。

为什么不是 128B 或 128C?起始符图案怎么看?

起始 A / B / C 的图案分别是 211412、211214、211232,三者都以 211 开头,靠后面几位区分。本页只用 B 和 C:含字母或标点的内容走 B(起始符值 104),纯数字偶数位走 C(起始符值 105)。码集 A 面向 ASCII 控制符场景,日常编号用不到,所以没有开放。

下载的 PNG 打印出来扫不出来,先查什么?

按这个顺序查:① 标签软件有没有把图片缩放成非整数比例(会把条宽变成 1 px、2 px 交替);② 打印分辨率够不够,203 dpi 下 X 至少要 2 dot;③ 左右静区是不是被裁掉了;④ 条码高度太矮(低于 30 px 换算到打印尺寸后过矮)。四条都排除之后再怀疑内容或校验位。

画布左右那两段空白能去掉省点地方吗?

不建议。那两段空白各 10 个模块,是 ISO/IEC 15417 对 Code 128 规定的静区下限,读码器靠它定位条码起点。裁掉之后条空图案本身没错,但扫描枪可能完全读不到。真要省宽度,缩短内容或者降低 X 尺寸更有效。

内容超过 40 个字符会怎样?

输入框本身设了 40 字符上限,粘贴超长文本时会被截到 40 个字符;如果通过脚本改了输入框的值,编码前也会拦住并提示当前字符数。Code 128 标准没有这个限制,是页面为了控制画布宽度设的。

中文能编成 Code 128 吗?

不能。Code 128 的三个码集只覆盖 ASCII,中文汉字要先用 UTF-8 或 GBK 转成字节,再按字节逐个编码;即便这么做,得到的也不是"人能读的中文条码",只是字节串。中文内容请改用二维码。

X 填 2 和填 3 除了宽度还有什么区别?

只有宽度和可读性差别,编码结果的数值序列、校验位、模块数完全一致。X 越大,同样长度内容的条码越宽,但单条最小宽度也越大、越容易被低分辨率扫描枪读到。排不下时优先缩内容,其次才是缩 X,并且缩完要用实际打印机试扫。

相关工具