IS08583报文协议包的解析和封装java源代码
2011-09-20 14:55
375 查看
一:IS08583包介绍: ISO8583包(简称8583包)是一个国际标准的包格式,最多由128个字段域组成,每个域都有统一的规定,并有定长与变长之分。 8583包前面一段为位图,用来确定包的字段域组成情况。其中位图是8583包的灵魂,它是打包解包确定字段域的关键, 而了解每个字段域的属性则是填写数据的基础。 1:位图说明: 位置:在8583包的第1 位 格式:定长 类型:B16(二进制16位,16*8=128bit) 描述: 如将位图的第一位设为'1',表示使用扩展位图(128个域),否则表示只使用基本位图(64个域)。 如使用某数据域,应在位图中将相应的位设位'1',如使用41域,需将位图的41位设为'1'。 选用条件:如使用65到128域,需设位图域第一位为'1' 2:域的定义: typedef struct ISO8583 { int bit_flag; /*域数据类型0 -- string, 1 -- int, 2 -- binary*/ char *data_name; /*域名*/ int length; /*数据域长度*/ int length_in_byte;/*实际长度(如果是变长)*/ int variable_flag; /*是否变长标志0:否 2:2位变长, 3:3位变长*/ int datatyp; /*0 -- string, 1 -- int, 2 -- binary*/ char *data; /*存放具体值*/ int attribute; /*保留*/ } ISO8583; 二:定义BitMap类 类说明:根据ISO8583 包的域定义,定义BitMap类存储每个域的信息。例如: package com.lottery.pos.model; public class BitMap { private int bit; //位 private int bittype; //数据类型 1 ascii 2 binary private int variable; //是否变长0 不是 2 两位变长 3 三位变长 private int len; //数据长度 private byte[] dat; //数据 public int getBit() { return bit; } public void setBit(int bit) { this.bit = bit; } public int getBittype() { return bittype; } public void setBittype(int bittype) { this.bittype = bittype; } public int getVariable() { return variable; } public void setVariable(int variable) { this.variable = variable; } public byte[] getDat() { return dat; } public void setDat(byte[] dat) { this.dat = dat; } public int getLen() { return len; } public void setLen(int len) { this.len = len; } } 三:定义PortConfig类 类说明:定义配置信息类。根据此类解析和封装数据。例如: package com.lottery.pos.model; public class PortConfig { /** * 存放所有接口的配置信息 * [][0] bit 位:在Map中的位 * [][1] type 类型:1 ascii 2 binary * [][2] len 长度:(对定长有效) * [][3] varLen 变长:0非变长 2位变长 3位变长 */ // 定义一个二位数组存放配置信息。 public static final int[][] config= { {11,1,6,0}, {12,1,6,0}, {13,1,4,0}, {32,1,11,0}, {37,1,12,0}, {39,1,2,0}, {40,2,50,2}, {41,1,8,0}, {48,1,52,3}, {120,2,128,3}, }; } 四:定义BitMapiso类 类说明:此类提供解析请求包和封装信息包两个方法,例如: package com.lottery.pos.utils; import java.util.ArrayList; import java.util.List; import com.lottery.pos.model.BitMap; public class BitMapiso { /** * 解析请求包 * @param body * @param config * @return List */ @SuppressWarnings("unchecked") public static List unpackRequest(byte[] body, int[][] config) { List outList = new ArrayList(); // 取得除信息类型以外的包信息。也就是取得位图的初始位置。 byte[] realbody = new byte[body.length - 4]; System.arraycopy(body, 4, realbody, 0, realbody.length); // 取得位图 byte[] map = null; byte[] map8 = new byte[8]; System.arraycopy(realbody, 0, map8, 0, 8); boolean[] bmap8 = LoUtils.getBinaryFromByte(map8); if (bmap8[1]) { // 如果第一位为1,则是可扩展位图,设为16字节长度。 map = new byte[16]; System.arraycopy(realbody, 0, map, 0, 16); } else { map = map8; } boolean[] bmap = LoUtils.getBinaryFromByte(map); int tmplen = map.length; for (int i = 2; i < bmap.length; i++) { if (bmap[i]) { //BitMap bitMap = null; // 寻找位图中的1对应的数据 int bit=-1; for (int j = 0; j < config.length; j++) { if (config[j][0] == i) { bit=j; break; } } BitMap outBitMap = new BitMap(); outBitMap.setBit(i); outBitMap.setBittype(config[bit][1]); //len对变长是无用的。 outBitMap.setLen(config[bit][2]); outBitMap.setVariable(config[bit][3]); byte[] nextData = null; if (config[bit][3] > 0) { //取出变长部分的值。 int varLen = config[bit][3]; if (config[bit][1] == 2) { varLen = varLen - 1; } byte[] varValue = new byte[varLen]; System.arraycopy(realbody, tmplen, varValue, 0, varValue.length); int datLen = 0; if (config[bit][1] == 2) { datLen = LoUtils.bcdToint(varValue); } else { datLen = byteToInt(varValue); } tmplen += varLen; // 取出变长部分后带的值。 nextData = new byte[datLen]; System.arraycopy(realbody, tmplen, nextData, 0,nextData.length); tmplen += nextData.length; } else { nextData = new byte[config[bit][2]]; System.arraycopy(realbody, tmplen, nextData, 0,nextData.length); tmplen += config[bit][2]; } outBitMap.setDat(nextData); outList.add(outBitMap); } } return outList; } /** * 打包响应包,不包括消息类型 * @param list * @return byte[] */ @SuppressWarnings("unchecked") public static byte[] PackResponse(List list) { int len = 16; for (int i = 0; i < list.size(); i++) { BitMap bitMap = (BitMap) list.get(i); // 计算请求包总长度 if (bitMap.getBittype() == 2) { if (bitMap.getVariable() > 0) { len += bitMap.getVariable() - 1 + bitMap.getDat().length; } else { len += bitMap.getVariable() + bitMap.getDat().length; } } else { len += bitMap.getVariable() + bitMap.getDat().length; } } byte[] body = new byte[len]; // 位图 boolean[] bbitMap = new boolean[129]; bbitMap[1] = true; int temp = (bbitMap.length - 1) / 8; for (int j = 0; j < list.size(); j++) { BitMap bitMap = (BitMap) list.get(j); bbitMap[bitMap.getBit()] = true; byte[] bitmap = LoUtils.getByteFromBinary(bbitMap); System.arraycopy(bitmap, 0, body, 0, bitmap.length); // 数据 if (bitMap.getVariable() > 0) { // 数据是可变长的:拼变长的值 byte[] varValue = null; if (bitMap.getBittype() == 2) { varValue = LoUtils.StrToBCDBytes(String.format("%0"+ bitMap.getVariable() + "d",bitMap.getDat().length)); } else { varValue = String.format("%0" + bitMap.getVariable() + "d",bitMap.getDat().length).getBytes(); } System.arraycopy(varValue, 0, body, temp, varValue.length); temp += varValue.length; // 拼变长部分后所带的数的值。 System.arraycopy(bitMap.getDat(), 0, body, temp, bitMap.getDat().length); temp += bitMap.getDat().length; } else { // 数据是固定长度的。 byte dat[] =new byte[bitMap.getLen()]; if (bitMap.getDat().length!=bitMap.getLen()){ System.arraycopy(bitMap.getDat(), 0, dat, 0, bitMap.getLen()); }else{ dat=bitMap.getDat(); } System.arraycopy(dat, 0, body, temp, dat.length); temp += bitMap.getDat().length; } } return body; } }
相关文章推荐
- IS08583报文协议包的解析和封装java源代码
- IS08583报文协议包的解析和封装java源代码
- IS08583报文协议包的解析和封装java源代码
- IS08583报文协议包的解析和封装java源代码
- IS08583报文协议包的解析和封装java源代码
- IS08583报文协议包的解析和封装java源代码
- IS08583报文协议包的解析和封装java源代码 【转】
- Q / GDW 376.1—2009电力用户用电信息采集系统通信协议报文解析示例
- 网络协议:SNMP协议PDU报文格式解析
- 报文解析各协议结构体
- Wireshark解析自定义协议数据报文
- HTTP 协议报文解析
- HL7协议报文的解析脚本
- J8583CN解析ISO8583协议报文注意点
- 常用传感器协议5:CJ/T-188 水表协议解析2
- RocketMQ原理解析-Remoting2. 通信层底层传输协议
- 解析pcap文件,提取具有指定协议的特征字符串的数据包
- 写协议解析程序的过程(关于通信解析函数的理解)
- TCP协议疑难杂症全景解析
- java文件上传报文解析与实现