barcode4j CODE128/EAN128生成 不定长 msg值 分隔符
作者:互联网
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,其对应的字符值与字符本身相同。
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