我帮一个朋友的小仓库贴过两千多个货位标签,第一版打完拿扫描枪去扫,十个里有三个扫不出来,另有一个更难看的问题:他供货给一家连锁门店,门店的收银系统直接拒收,理由是"你这个条码扫不出商品"。那之前我以为条形码是"把数字画成黑白条",做完才明白,能不能用取决于两件完全不同的事:码制选得对不对,以及这个编号你有没有权利自己编。
先问清楚这个码要给谁扫
这是我从那两千张标签里学到的第一条。只在自家库房、自家资产台账里流转的码,怎么编号没人管,扫的也是你自己的设备,选码只看两件事:要不要带字母、要不要带小数点。要进别人零售体系的码不一样,它的编号是全局的,收银系统扫出来的那串数字得能对应到你注册过的厂商代码,这种情况下不是选码制的问题,是先要有合法编号。
我在 条形码生成器 里能选的也就这三种主流码制:CODE128、EAN-13、CODE39,条宽 1 到 5 像素、高度 40 到 200 像素可以自己调,前景背景色可选,白边和条码下方那行文字也能开关,出来是 PNG。
三种码制的字符范围和校验位
| 码制 | 能编什么字符 | 长度 | 校验位 | 我那次用它做什么 |
|---|---|---|---|---|
| CODE128 | ASCII 32 到 126 的可打印字符,共 95 个 | 可变长度 | 有,按模 103 由编码器补在末尾 | 货位号和带字母的资产编号 |
| EAN-13 | 只有数字 0 到 9 | 固定 13 位 | 有,第 13 位由前 12 位加权算出 | 零售商品包装上的条码 |
| CODE39 | 大写 A 到 Z、数字 0 到 9,加空格和 - . $ / + % 七个符号,共 43 个字符 | 可变长度 | 码制本身不带算术校验位,靠起止符自校验 | 仪器上的序列号,老扫描枪只认它 |
三行里最容易被忽略的是 CODE39 那一列。它没有内置的算术校验位,有些扫描枪或系统会要求额外附加一位按模 43 的校验字符,那是设置项而不是码制自带的。CODE39 还有扩展写法,用小写和符号要靠成对字符拼,同样的内容会比 CODE128 长不少。我遇到只有 CODE39 能读的老设备时,会先确认它有没有开扩展和校验,不然打出来的标签在别处扫不出。
要全字符又要短,CODE128 一般是最优解,这是我给货位标签换码制的原因:同一个编号,CODE39 的扩展写法要占两倍宽度。
EAN-13 的校验位手算一遍
我一开始不知道第 13 位是算出来的,编了一串自己按下去,扫枪报错,还以为是打印问题。算法不复杂,我把过程留下,方便对着核。
拿我随手拟的一串 12 位数字 690123456789 做例子(这只是练习用的号码,不是哪个真实商品的注册号)。从左往右数,第 1、3、5、7、9、11 位相加:6+0+2+4+6+8=26。第 2、4、6、8、10、12 位相加:9+1+3+5+7+9=34,这个和要乘 3,得 102。两部分合起来 26+102=128,看个位数是 8,用 10 去减得 2,校验位就是 2,完整条码是 6901234567892。如果个位正好是 0,校验位记 0,不是记 10。
再拿一组核对:12 位 123456789012,奇位和 1+3+5+7+9+1=26,偶位和 2+4+6+8+0+2=22,22 乘 3 是 66,26+66=92,个位 2,10 减 2 得 8,所以完整是 1234567890128。两遍算下来我才信"生成器勾了 EAN-13 就会自动补校验码"这件事,前 12 位填错一个数字,校验位就不匹配,扫枪直接拒读——这是保护,不是毛病。
前缀这件事不能自己编
EAN-13 那 13 位不是一个自由数字空间。它按"前缀加厂商代码、商品项目代码、校验位"来分,而前缀这一段要落到 GS1 的组织体系里,厂商识别代码需要向对应的编码组织申请,国内常见的 690 到 699 开头就属于这个体系里分配给国内厂商的号段。没注册而自己拼一个 690 开头的号码,扫出来是别人的商品,进了零售系统就是撞码,被拒收是我朋友遇到的最轻的结果。真要走这条路,正确做法是去申请,不是找个生成器凑。
如果只是内部编号,我的建议很直接:别用 EAN-13。它只能放数字、长度还锁死在 13 位,你要写"货架A-第3层"这种带字母的编号根本放不进去。
能扫出来,靠的是打印而不只是编码
那三个扫不出来的标签,问题全在物理层面。条码读的是黑白条的宽度,条宽像素乘以打印机的点距就是实际模块宽度:203 dpi 的热敏机一个点约 0.125 毫米,我把条宽设 3 像素,实际约 0.375 毫米;同一张图换 300 dpi 打,3 像素缩到约 0.254 毫米;600 dpi 只有约 0.127 毫米。热敏打印在细线条上还会往两边洇,白条被"吃掉"一点,解码器就分不出 1 个模块和 2 个模块。我后来把内部标签的条宽调到 4 像素,重打一次三个全过了。
另外两条我踩过:一是两侧要留白,也就是静默区,扫描枪靠这段空白判断条码从哪开始,我一开始为省标签纸把白边关掉,读不出来;二是颜色,工具允许改前景和背景色,但常见的扫描枪是红光光源,红色在它眼里几乎和白色一样亮,所以红底、红条都别试,深浅对比够强就行,不必非要纯黑。
打出来我不靠手感验收,会拍照上传 条形码解码 读一遍,能把那串数字原样读回来才算数。要承载的是一长段文本或者扫码后要直接跳转,一维码就不合适了,那种内容我改用 二维码生成器。
常见问题
Q:超市要求我提供条码,我自己生成一个行不行?
不行。EAN-13 的号段要经 GS1 体系分配,自拟的号码会和真实商品撞。生成器能算出合法的校验位,但算不出合法的厂商代码。
Q:库房编号里有字母,该选哪个码制?
选 CODE128。EAN-13 只能放 13 位纯数字,CODE39 能放但只认大写和七个符号,同样内容还要占更宽。
Q:为什么我的码打印出来扫不出来?
我遇到过的原因按概率排:条宽太细撑不住打印精度、两侧没留白边、放大缩小后线条边缘发虚、颜色对比在红光下失效。先把条宽加一档、白边打开,再重打一张试。
Q:校验位算错了会怎样?
扫枪通常直接不读,而不是读成另一个数,因为校验位就是用来发现这种错的。手工填 EAN-13 时前 12 位打错一个数字,校验位就对不上。
Q:CODE39 和 CODE128 能混用在同一批标签上吗?
能,但要看扫描枪的设置和识别范围。我的做法是同一个体系里只用一种,混用带来的排查成本比省下的那点宽度大得多。
回到那两千张标签。最后内部货位全部换成 CODE128、条宽 4 像素、白边打开、打完抽样解码验证;供货给门店的那批没有继续用自编号,而是等厂商代码批下来才重新印。判断标准其实很清楚:只在自家流转,选码制看字符集和宽度;要出门进别人的收银系统,先解决编号归属,再谈生成器。