ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

barcode4j CODE128/EAN128生成 不定长 msg值 分隔符

2021-01-04 12:00:31  阅读:212  来源: 互联网

标签:Code CODE128 編碼 條碼 字符集 EAN128 bean barcode4j 128


barcode4j EAN128不定长msg分隔符

条形码

首先我们需要了解条形码是怎样的。

CODE128: Code128码可表示ASCII 0到ASCII 127共计128个ASCII字符,由于其字符集大,密度高,应用非常广泛。
国际UCC/EAN组织有一个专门的关于128码的条码标识标准,就是UCC/EAN128码,这种128码在全球范围内有统一的编码规范和解释。

对照编码表,95270078 编码表示为:开始位StartA(bbsbssssbss)+ 数据位[9(bbbssbsbbss)+ 5(bbsbbbssbss)+ 2(bbssbbbssbs)+ 7(bbbsbbsbbbs)+ 0(bssbbbsbbss)+ 0(bssbbbsbbss)+ 7(bbbsbbsbbbs)+ 8(bbbsbssbbss)]+ 检验位21(bbsbbbssbss)+ 结束位Stop(bbsssbbbsbsbb), 即:bbsbssssbssbbbssbsbbssbbsbbbssbssbbssbbbssbsbbbsbbsbbbsbssbbbsbbssbssbbbsbbssbbbsbbsbbbsbbbsbssbbssbbsbbbssbssbbsssbbbsbsbb。 若要打印,只需将b用黑色线标出,s用白色线标出,一个简单的条形码生成程序就完成了! [^1]

128B 与128A类似,128C只能对长度为偶数的数字串编码,每两个数字为一位,所以输出的信息压缩了一半,打印的条形码因此也就较短。接上例,第1位数据 95对应ID为95,第2位数据27对应ID为27,第3位数据00对应ID为0,第4位数据78对应ID为78,所以检验位 = (105 + 195 + 227 + 30 + 478) % 103 = 51

EAN128与Code128C相同,只是在开始位后加多一个控制位FNC1(ID为102),同时将FNC1做为第1位数据加入到检验位的计算。

各种方式的编码结果罗列如下:

编码方式 开始位 FNC1 数据位 检验位 结束位 编码结果
Code128A StartA 无 9 + 5 + 2 + 7 + 0 + 0 + 7 + 8 (103 + 125 + 221 + 318 + 423 + 516 + 616 + 723 + 824) % 103 = 21 Stop bbsbssssbssbbbssbsbbssbbsbbbssbssbbssbbbssbsbbbsbbsbbbsbssbbbsbbssbssbbbsbbssbbbsbbsbbbsbbbsbssbbssbbsbbbssbssbbsssbbbsbsbb
Code128B StartB 无 9 + 5 + 2 + 7 + 0 + 0 + 7 + 8 (104 + 125 + 221 + 318 + 423 + 516 + 616 + 723 + 824) % 103 = 22 Stop bbsbssbssssbbbssbsbbssbbsbbbssbssbbssbbbssbsbbbsbbsbbbsbssbbbsbbssbssbbbsbbssbbbsbbsbbbsbbbsbssbbssbbssbbbsbssbbsssbbbsbsbb
Code128C StartC 无 95 + 27 + 00 + 78 (105 + 195 + 227 + 30 + 478) % 103 = 51 Stop bbsbssbbbssbsbbbbsbsssbbbsbbssbssbbsbbssbbssbbssssbsbssbbsbbbsbsssbbsssbbbsbsbb
EAN128 StartC FNC1 95 + 27 + 00 + 78 (105 + 1102 + 295 + 327 + 40 + 5*78) % 103 = 44 Stop bbsbssbbbssbbbbsbsbbbsbsbbbbsbsssbbbsbbssbssbbsbbssbbssbbssssbsbssbsssbbsbbbsbbsssbbbsbsbb

在这里插入图片描述

Code 128 條碼

Code 128 編碼方式是屬於比較複雜的一種條碼,應用起來比較有彈性,在1981年開始流行起來。

Code 128 條碼主要特性有:

1.有A,B,C三種不同的編碼型態,可以提供128個標準的ASCII code字元.

包括: 0~9的數字,英文大小寫,各種特殊符號,以及控制碼。

2.有一檢查碼,可自由決定是否要列印。

3.在可藉由A、B、C三種不同編碼型態交叉使用,以縮短條碼的長度。

4.可允許由左至右,或由右至左,雙向掃瞄。

Code 128 條碼基本結構

圖一

Code 128 條碼內容主要有四個部份:

1.起始碼 (start code)

2.資料碼 (data code)

3.結束碼 (end code)

4.檢查碼 (check code):可有可無

Code 128 條碼字元編碼方式

Code 128 每一字元條碼結構由3條Bar及3條Space所組成.又細分為11等分,組成不同粗細比。字元最粗的線條最高可達最細的4倍。

例如:起始碼Code A

在这里插入图片描述

11010000100 條碼裡頭space最粗是最細線條的4倍

再舉個例子,我們以B型態中的特殊符號’/'說明

在这里插入图片描述

10111001100 最粗的bar是最細bar的3倍

起始碼與結束碼編碼方式

Code 128 條碼有A、B、C三種不同型態編碼的字元表,要選擇哪一種字元表取決於特殊控制碼Code A,Code B與Code C。

起始碼也有三種編碼型態:Code A,Code B,Code C

當起始碼為Code A時,後面的條碼資料則選擇A型態字元表編碼邏輯。

而起始碼為Code B時,後面的條碼資料則選擇B型態字元表編碼邏輯。

若全部為數字時可選擇Code C型態字元表編碼邏輯,以縮短條碼的列印長度。

每一類型的字元表內也有Code A,Code B,Code C,但條碼編碼邏輯與起始碼不同,請參閱【Code 128 條碼字元表】

接下來我們看三種起始碼的條碼編碼方式

Code A條碼資料為11010000100,條碼圖案為 ,相對值為103。

Code B條碼資料為11010010000,條碼圖案為 ,相對值為104。

Code C條碼資料為11010011100,條碼圖案為 ,相對值為105。

結束碼編碼方式

A,B,C三種不同型態編碼方式,結束碼均固定為1100011101011,條碼圖案為,相對值為106。

Code 128 條碼三種字元表型態編碼差異說明

1.A 型態字元表,支援的資料碼包含:標準ASCII=0 ~ ASCII=95等字元及控制碼部份,以及7個Code 128 條碼專屬字元,共計103個字元,請參閱code 128 條碼字元表中的A型態。(ASCII=031為控制碼,ASCII=3295為可見字元。)

2.B型態字元表包含:標準ASCII=32 ~ ASCII=127等字元,以及7個Code 128 條碼專屬字元,共計103個字元,請參閱code 128 條碼字元表中的B型態。

3.C型態字元表主要支援數字0099的編碼使用,若使用長數字的資料時,可以用C型態編碼,可縮短條碼列印的長度。數字0099加上3個特殊控制字元,總共103個字元。

特殊控制字元說明

1.Code A:表示後面的字元編碼型態要使用A table。

2.Code B:表示後面的字元編碼型態要使用B table。

3.Code C:表示後面的字元編碼型態要使用C table。

4.Shift:等於Shift鍵的作用。

5.FNC 1:等於F1鍵的作用。

6.FNC 2:等於F2鍵的作用。

7.FNC 3:等於F3鍵的作用。

8.FNC 3:等於F4鍵的作用。

Code 128 條碼應用實例說明

1.Code C型態應用時機

我們舉以下例子,如果資料內如為數字0123456789,使用Code A及Code C條碼列印長度的差異,Code C條碼列印出來的長度較短。

Code A型態時的編碼如下圖

在这里插入图片描述

Code C型態時的編碼如下圖

在这里插入图片描述

2.Code A及Code C型態混合應用時機

在这里插入图片描述

前面4個字元ABCB使用A table編碼,所以起始碼以Code A開始,然後在數字0123456789之前加上Code C特殊控制碼,則後面的數字會轉換成C table編碼,如此就可以縮短條碼列印的長度。

Code 128 條碼檢查碼的計算方式

我們以起始碼Code B編碼的Andy’s條碼來說明

在这里插入图片描述

步驟一.計算出S值

S=103+(d11)+(d22)+ (d33)+ (d44)+ …

d1:表示資料第1個字元

因為起始碼為Code B,所以字元相對值使用B table。

則S=103+(331)+(782)+(683)+(894)+(75)+(836)=103+33+156+204+356+35+498=1385

步驟二.將S值除以103,取其餘數M值。

1385/103=13…46 ?取餘數M=46

步驟三.將M值46代入B table找到相對值的字元為N,即檢查碼為N。

提醒:

若資料碼裡有Code A,Code B,Code C型態轉換,檢查碼代入的依據均以起始碼相對應的字元組型態為主。

起始符(Unicode=00CC):ì

终止符(Unicode=00CE):Î

value95(Unicode=00C3):Ã

value96(Unicode=00C4):Ä

value97(Unicode=00C5):Å

value98(Unicode=00C6):Æ

value99(Unicode=00C7):Ç

value100(Unicode=00C8):è

value101(Unicode=00C9):é

value102(Unicode=00CA):ê
找这些确定那个起始符,终止符的ID105,106对应的编码含义找了半天,一开始对应ASCII码表查,怎么都不对

CODE128 代码实现

	<dependency>
	    <groupId>net.sf.barcode4j</groupId>
	    <artifactId>barcode4j-light</artifactId>
	    <version>2.0</version>
	</dependency>


public static String generateByCODE128(String msg, String filePath,double width,double height,int fontSize ) throws Exception {
    File file = new File(filePath);
    if (!file.getParentFile().exists()) {
        file.getParentFile().mkdirs();
    }
    OutputStream ous = new FileOutputStream(file);
    if (StringUtils.isEmpty(msg) || ous == null) {
        return null;
    }

    Code128Bean bean = new Code128Bean();
    // 精细度
    int dpi = 300;
    // 配置对象
    bean.setModuleWidth(width);//模型宽度
    bean.setBarHeight(height);//条形码高度
    bean.doQuietZone(false);//是否有空白区
    bean.setFontSize(fontSize);//字号2
    bean.setFontName("Helvetica");//字体
    bean.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);//字的位置
    
    String format = "image/png";//输出格式
    //位地图扫描系统提供器
    BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format, dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
    // 生成条形码
    bean.generateBarcode(canvas, msg);
    // 结束绘制
    canvas.finish();
    ous.close();
    return filePath;
}

EAN128代码实现

EAN128与Code128C相同,只是在开始位后加多一个控制位FNC1(ID为102),同时将FNC1做为第1位数据加入到检验位的计算。

EAN是两位两位进行转换的。

如何改变文本的样式

public static String generateByEAN128(String msg, String filePath,double width,double height) throws Exception {
    File file = new File(filePath);
    if (!file.getParentFile().exists()) {
        file.getParentFile().mkdirs();
    }
    OutputStream ous = new FileOutputStream(file);
    if (StringUtils.isEmpty(msg) || ous == null) {
        return null;
    }

    EAN128Bean bean = new EAN128Bean();
    // 精细度
    int dpi = 300;
    // 配置对象
    bean.setModuleWidth(width);
    bean.setBarHeight(height);
    bean.doQuietZone(false);
    bean.setFontSize(2);
    bean.setFontName("Helvetica");
    bean.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
    String format = "image/png";

    BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format, dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
    // 生成条形码
    bean.generateBarcode(canvas, msg);
    // 结束绘制
    canvas.finish();
    ous.close();
    return filePath;
}

EAN128常见错误-不定长数据报错

期待输出:
在这里插入图片描述

//使用如下代码报错
BarcodeUtil.generateByEAN128("10D2004112012101723120921017134", "F:\\testBarcode\\generateByEAN128.jpg", 0.4, 10);

java.lang.IllegalArgumentException: Variable length field “D2004112012101723120921017134” too long! Length should be 20 at the most! Accepted start of Message: “(10)”
at org.krysalis.barcode4j.impl.code128.EAN128LogicImpl.getException(EAN128LogicImpl.java:363)
at org.krysalis.barcode4j.impl.code128.EAN128LogicImpl.getException(EAN128LogicImpl.java:352)
at org.krysalis.barcode4j.impl.code128.EAN128LogicImpl.addAI(EAN128LogicImpl.java:212)
at org.krysalis.barcode4j.impl.code128.EAN128LogicImpl.addAIs(EAN128LogicImpl.java:143)
at org.krysalis.barcode4j.impl.code128.EAN128LogicImpl.setMessage(EAN128LogicImpl.java:74)
at org.krysalis.barcode4j.impl.code128.EAN128LogicImpl.generateBarcodeLogic(EAN128LogicImpl.java:106)
at org.krysalis.barcode4j.impl.code128.EAN128Bean.generateBarcode(EAN128Bean.java:78)

//正确如下:
BarcodeUtil.generateByEAN128("10D2004"+"ñ"+"112012101723120921017134", "F:\\testBarcode\\generateByEAN128.jpg", 0.4, 10);
//ñ是jar包中关于分隔不定长的特殊字符,以下为barcode4j-EAN128LogicImpl中的内容
/*     */   private int findGroupSeparator(String msg, int start) {
/* 148 */     int retGS = msg.indexOf(this.groupSeparator, start);
/* 149 */     if (this.groupSeparator == 'ñ') {
/* 150 */       return retGS;
/*     */     }
/* 152 */     int retF = msg.indexOf('ñ', start);
/* 153 */     if (retGS <= 0) {
/* 154 */       return retF;
/*     */     }
/* 156 */     if (retF <= 0) {
/* 157 */       return retGS;
/*     */     }
/* 159 */     return Math.min(retGS, retF);
/*     */   }

关于阅读jar包内容

eclipse没法直接反编译,用了插件也看不了,更不要妄想打断点调试了。

所以自己下载了java Decompiler。
可以打开jar包,搜索关键字,输出java文件。
还是挺好用的。

其他参考

EAN-128码,现称GS1-128码,是专用于GS1系统中的条码,可以标注商品的附加信息,在商品信息的标识、产品的跟踪与追溯中有广泛的用途。
EAN-128码来自于CODE-128码,在字符集、条空规则上与CODE-128码完全一致,因此我们需要先来介绍一下CODE-128码。
CODE-128码是一种用模块组配法编制的条码,三套字符集共可以表示128个符号,故称128码,字符集包含数字,大小写英文字母、符号、控制符和00-99的100个双位数的数字。每个字符的条码符号由三条三空11个模块组成,终止符为四条三空13个模块。下图是三个字符集的字符与条空结构对照表。由图中可以看出,与商品条码的三个子集不同,三个字符集共用一套条空结构,每一个字符集都有107个符号,每一个符号都有一个字符值。字符集A和字符集B中的字符大部分是重叠的,只有字符值64以后的符号不同,字符集A中包含了控制符,而字符集B中包含了小写字母;字符集C除了最后七个辅助字符外,只包含了100个双位数的数字,由00-99,其对应的字符值与字符本身相同。
条码知识之九:EAN-128条码(上)

   CODE-128码的编码规则:一个CODE-128条码由左空白区、起始符、数据字符、校验符、终止符、右空白区和供人识读的字符构成。

   1、起始符有三个,分别是START A,START B和START C,起始符说明了该条码中的数据使用的字符集。当表示的数据是四个或四个以上连续的数字时,必须使用START C,以缩短条码的长度。

   2、校验符由起始符和数据区的字符值决定,其计算方法参见之前的《校验码的计算》一文。CODE-128码的校验符是条码本身的特性,它不是数据的一部分,因此校验符不会在供人识读的数据中出现。

   3、终止符STOP由四条三空13个模块构成,三个字符集的终止符是同一个符号。

   由于字符集B中包含了比较丰富的字符,所以表示由英文字母和符号构成的数据时通常都会选用B字符集,如果只用大写字母则选字符集A和字符集B是一样的。

   编码示例:(1)BEIJING'08   (2) GS1-CHINA   (3)20091020

   (1) |START A| B | E | I | J | I | N | G | ' | 0 | 8 |校验符|STOP|   (使用A字符集)

   把以上字符对应的条空结构连接起来就构成了一个表示BEIJING'08的条码符号。
   (2) |START B| G | S | 1 | - | C | H | I | N | A |校验符|STOP| (使用B字符集)

   (3) |START C|20|09|10|20|校验符|STOP|  (使用C字符集)

   *注意使用C字符集的(3)与使用A字符集的(1)中表示数字的不同点,AB字符集只能表示单个的数字,而C字符集每一个条码符号都表示2位数字。

   CODE-128条码允许在条码中间改变使用的字符集,这个功能依靠另外三个辅助字符来完成:CODE A,CODE B,CODE C。例如POSTCODE450002用128条码表示:

   |START A| P | O | S | T | C | O | D | E | 4 | 5 | 0 | 0 | 0 | 2 |校验符|STOP|

  全部使用A字符集,一共要使用17个码字。如果把数字部分改用C字符集就会缩短条码的长度,使用15个码字:

   |START A| P | O | S | T | C | O | D | E |CODE C| 45 | 00 | 02 |校验符|STOP|

   另一个辅助字符SHIFT可以使其后的一个字符从字符集A进入字符集B或从字符集B进入字符集A,之后的第二个字符及以后的符号仍然回到原字符集,它不能进入或退出字符集C。例:

   |START B| C | h | i | n | a |SHIFT| CR | W | o | r | l | d |校验符|STOP|

  该条码在阅读时可以产生以下效果:

  China

  World

   原因是SHIFT让其后的一个字符CR使用了字符集A,而CR是计算机中的回车键,即在读出China后产生一个回车键再读World。

参考资料
[1]: http://news.eeworld.com.cn/mcu/2014/1204/article_17453_2.html
[2]: http://blog.sina.com.cn/s/blog_3fed3a3901017sth.html

标签:Code,CODE128,編碼,條碼,字符集,EAN128,bean,barcode4j,128
来源: https://blog.csdn.net/m0_37115811/article/details/112170838

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有