V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
jamesliu96
V2EX  ›  分享创造

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

  •  
  •   jamesliu96 ·
    jamesliu96 · 2014-03-31 11:33:10 +08:00 · 5692 次点击
    这是一个创建于 3650 天前的主题,其中的信息可能已经有所发展或是发生改变。
    周末闲得没事干,偶然看见了一个包装袋上的条形码,觉得很有意思,之前写过一个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
    欢迎转载,转载请署名。
    15 条回复    1970-01-01 08:00:00 +08:00
    cnxh
        1
    cnxh  
       2014-03-31 11:46:11 +08:00   ❤️ 1
    感谢分享 mark
    loading
        2
    loading  
       2014-03-31 12:27:39 +08:00 via iPhone   ❤️ 1
    有无依赖的二维码生成库吗?
    sobigfish
        3
    sobigfish  
       2014-03-31 12:37:16 +08:00
    赞,期待table/svg的实现。
    sobigfish
        4
    sobigfish  
       2014-03-31 12:44:46 +08:00
    API有点奇怪,分3段输入,还是12位,最后一位不要?
    sobigfish
        5
    sobigfish  
       2014-03-31 12:52:22 +08:00   ❤️ 1
    随便找了个正式的ean 6908471004470
    在demo上console里报错了
    var ean = new EAN13(690, 8471, 00447);
    jamesliu96
        6
    jamesliu96  
    OP
       2014-03-31 13:30:15 +08:00
    @sobigfish 首先,谢谢支持~ 对于你说的报错的问题,你看看你输入的第三个参数00447是number类型的.toString()方法之后是447所以位数不对,这个问题我在解决,但是你输入的时候尝试var ean = new EAN13(690, 8471, "00447");即可解决问题了。
    sobigfish
        7
    sobigfish  
       2014-03-31 13:52:56 +08:00 via iPad
    噗,原来是我常识性错误
    jamesliu96
        8
    jamesliu96  
    OP
       2014-03-31 13:57:49 +08:00
    @sobigfish 没事啦。这种事大家都常犯的。代码写多了脑子就木。多休息休息。我也在想有没有比一个一个加0更简单的方法。
    jamesliu96
        9
    jamesliu96  
    OP
       2014-03-31 14:36:33 +08:00
    @loading sorry我不明白你在说什么。第一,EAN13不是二维码而是条形码按理说是一维的;第二,这段代码不依赖任何库。Canvas输出的DEMO在这里http://g.jamesliu.info/ean13
    loading
        10
    loading  
       2014-03-31 14:39:16 +08:00 via iPhone
    @jamesliu96 我是搭车求库而已,大哥,息怒…
    sobigfish
        11
    sobigfish  
       2014-03-31 15:04:42 +08:00 via iPad
    @loading qr的Github上有 搜了过滤语言加star排序就OK了
    sobigfish
        12
    sobigfish  
       2014-03-31 15:06:20 +08:00 via iPad
    @jamesliu96 直接13 位输入,不管输入有效性可以生成不
    jamesliu96
        13
    jamesliu96  
    OP
       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
        14
    jamesliu96  
    OP
       2014-04-02 13:21:32 +08:00   ❤️ 1
    @sobigfish 初始化的问题我解决了,用到了arguments来操作参数
    https://github.com/jamesliu96/ean13/blob/master/ean13.js
    还加了canvas绘图的方法,准备下一步写一个生成svg
    jamesliu96
        15
    jamesliu96  
    OP
       2014-04-02 21:15:46 +08:00
    @sobigfish svg放弃了,太难写,我又懒得用第三方库,就加了个下载的功能,通过把canvas图像提取转换成png然后输出。
    http://g.jamesliu.info/ean13/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4132 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:00 · PVG 09:00 · LAX 18:00 · JFK 21:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.