闲的没事干用 JavaScript 写了个 EAN13 条形码生成器

2014-03-31 11:33:10 +08:00
 jamesliu96
周末闲得没事干,偶然看见了一个包装袋上的条形码,觉得很有意思,之前写过一个PDF417的生成器,大体上原理差不多,这次用JavaScript写了段EAN13条形码的生成器,可以得到二进制码,从而进行Canvas绘图。代码在这里: https://github.com/jamesliu96/ean13/blob/master/ean13.js Demo地址: http://g.jamesliu.info/ean13

EAN13是European Article Number 13的缩写,正如其名,它拥有13位数字,是国际上普遍使用的商品标识码。

EAN13码的结构大体上是这样的:
前3位:国家码,我国可以使用的是690到699。
之后4位:生产商代码,如3943。
后5位:产品代码,如03457。

最后一位是生成的校验码,算法如下:
假设前12位是690123456789,遍历将奇数位和偶数位分别求和:
奇数位和 = 6 + 0 + 2 + 4 + 6 + 8 = 26
偶数位和 = 9 + 1 + 3 + 5 + 7 + 9 = 34
奇数位和和偶数位和的3倍相加,得到总和:
总和 = 奇数位和 + 偶数位和 * 3 = 26 + 34 * 3 = 128
取总和的个位数:
个位 = 总和 % 10 = 8
将10与个位相减,得到校验位:
校验位 = 10 - 个位 = 2
注意:如果个位为0,校验位不是10 - 0 = 10而是0,我们可以使用判断但是这里有一个更好的算法就是将相减之后的数再除以10取余:
校验位 = (10 - 个位) % 10 = 2

这样我们就得到了整个EAN13码:6901234567892

接下来就是生成二进制的码。
生成二进制码的时候我们将第一位(e.g. 6)看作前置码,来决定使用的码集。
索引:
{
0: [0, 0, 0, 0, 0, 0],
1: [0, 0, 1, 0, 1, 1],
2: [0, 0, 1, 1, 0, 1],
3: [0, 0, 1, 1, 1, 0],
4: [0, 1, 0, 0, 1, 1],
5: [0, 1, 1, 0, 0, 1],
6: [0, 1, 1, 1, 0, 0],
7: [0, 1, 0, 1, 0, 1],
8: [0, 1, 0, 1, 1, 0],
9: [0, 1, 1, 0, 1, 0]
}
码集:
{
0: ["0001101", "0100111", "1110010"],
1: ["0011001", "0110011", "1100110"],
2: ["0010011", "0011011", "1101100"],
3: ["0111101", "0100001", "1000010"],
4: ["0100011", "0011101", "1011100"],
5: ["0110001", "0111001", "1001110"],
6: ["0101111", "0000101", "1010000"],
7: ["0111011", "0010001", "1000100"],
8: ["0110111", "0001001", "1001000"],
9: ["0001011", "0010111", "1110100"]
}
如果前置码是6,我们就用[0, 1, 1, 1, 0, 0]这个码集,前6位码得到的二进制码就是:000101101001110110011001101101111010100011,同样后6位则是:100111010100001000100100100011101001101100。
前面加上101起始符后面加上101终止符,前6位和后6位之间加上01010分隔符即可。

代码地址: https://github.com/jamesliu96/ean13/blob/master/ean13.js
Demo地址: http://g.jamesliu.info/ean13

欢迎来访 jamesliu96@Github
Copyright (C) 2014 James Liu
http://g.jamesliu.info
欢迎转载,转载请署名。
5730 次点击
所在节点    分享创造
15 条回复
cnxh
2014-03-31 11:46:11 +08:00
感谢分享 mark
loading
2014-03-31 12:27:39 +08:00
有无依赖的二维码生成库吗?
sobigfish
2014-03-31 12:37:16 +08:00
赞,期待table/svg的实现。
sobigfish
2014-03-31 12:44:46 +08:00
API有点奇怪,分3段输入,还是12位,最后一位不要?
sobigfish
2014-03-31 12:52:22 +08:00
随便找了个正式的ean 6908471004470
在demo上console里报错了
var ean = new EAN13(690, 8471, 00447);
jamesliu96
2014-03-31 13:30:15 +08:00
@sobigfish 首先,谢谢支持~ 对于你说的报错的问题,你看看你输入的第三个参数00447是number类型的.toString()方法之后是447所以位数不对,这个问题我在解决,但是你输入的时候尝试var ean = new EAN13(690, 8471, "00447");即可解决问题了。
sobigfish
2014-03-31 13:52:56 +08:00
噗,原来是我常识性错误
jamesliu96
2014-03-31 13:57:49 +08:00
@sobigfish 没事啦。这种事大家都常犯的。代码写多了脑子就木。多休息休息。我也在想有没有比一个一个加0更简单的方法。
jamesliu96
2014-03-31 14:36:33 +08:00
@loading sorry我不明白你在说什么。第一,EAN13不是二维码而是条形码按理说是一维的;第二,这段代码不依赖任何库。Canvas输出的DEMO在这里http://g.jamesliu.info/ean13
loading
2014-03-31 14:39:16 +08:00
@jamesliu96 我是搭车求库而已,大哥,息怒…
sobigfish
2014-03-31 15:04:42 +08:00
@loading qr的Github上有 搜了过滤语言加star排序就OK了
sobigfish
2014-03-31 15:06:20 +08:00
@jamesliu96 直接13 位输入,不管输入有效性可以生成不
jamesliu96
2014-03-31 19:46:09 +08:00
@sobigfish 好的,我有时间改一改。谢谢支持!请继续支持 :)

@loading QR的我以前写过,嫌弃它 :(,因为太普通了,没特色,QR现在遍大街都是,而且很多人写过。你可以看看https://github.com/jamesliu96/pdf417 我写的PDF417的生成二维码。DEMO: http://g.jamesliu.info/pdf417
jamesliu96
2014-04-02 13:21:32 +08:00
@sobigfish 初始化的问题我解决了,用到了arguments来操作参数
https://github.com/jamesliu96/ean13/blob/master/ean13.js
还加了canvas绘图的方法,准备下一步写一个生成svg
jamesliu96
2014-04-02 21:15:46 +08:00
@sobigfish svg放弃了,太难写,我又懒得用第三方库,就加了个下载的功能,通过把canvas图像提取转换成png然后输出。
http://g.jamesliu.info/ean13/

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/106607

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX