您的位置:首页 > 编程语言 > Java开发

IS08583报文协议包的解析和封装java源代码

2012-06-30 17:00 211 查看
一: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;

}



package com.lottery.utils;

import java.io.BufferedInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

/**

* 编码与数据类型类

*

* @author LLH

*/

public class LoUtils

{

private static BASE64Encoder encoder = new BASE64Encoder ();

private static BASE64Decoder decoder = new BASE64Decoder ();

/**

* BASE64 编码

*

* @param s

* @return

*/

public static String encodeBufferBase64(byte [] buff)

{

return buff == null ? null : encoder.encode (buff);

}

/**

* BASE64解码

*

* @param s

* @return

*/

public static byte [] decodeBufferBase64(String s)

{

try

{

return s == null ? null : decoder.decodeBuffer (s);

}catch (IOException e)

{

e.printStackTrace ();

}

return null;

}

/**

* BASE64 字节数组编码

*

* @param s

* @return String

*/

public static String encodeBase64(byte [] s)

{

if(s == null)

return null;

String res = new BASE64Encoder ().encode (s);

res = res.replace ("\n","");

res = res.replace ("\r","");

return res;

}

/**

* BASE64解码

*

* @param s

* @return

*/

public static byte [] decodeBase64(byte [] buff)

{

if(buff == null)

return null;

BASE64Decoder decoder = new BASE64Decoder ();

try

{

byte [] b = decoder.decodeBuffer (new String (buff));

return b;

}catch (Exception e)

{

return null;

}

}

/**

* 将reauest里的数据包转成字符串

*

* @param request

* @return String

*/

public static String getRequestBodyTxt(HttpServletRequest request)

{

// 接收手机传过来的参数

BufferedInputStream bufferedInputStream = null;

// 此类实现了一个输出流,其中的数据被写入一个字节数组

ByteArrayOutputStream bytesOutputStream = null;

String body = null;

try

{

// BufferedInputStream 输入流

bufferedInputStream = new BufferedInputStream (

request.getInputStream ());

bytesOutputStream = new ByteArrayOutputStream ();

// 写入数据

int ch;

while ((ch = bufferedInputStream.read ()) != -1)

{

bytesOutputStream.write (ch);

}

// 转换为String类型

body = new String (bytesOutputStream.toByteArray (),"UTF-8");

}catch (Exception ex)

{

ex.printStackTrace ();

}

finally

{

// 关闭此输入流并释放与该流关联的所有系统资源。

try

{

bytesOutputStream.flush ();

bytesOutputStream.close ();

bufferedInputStream.close ();

}catch (IOException e)

{

e.printStackTrace ();

}

}

return body;

}

/**

* 将reauest里的数据包转成字节数组

*

* @param request

* @return

*/

public static byte [] getRequestBodyByte(HttpServletRequest request)

{

// 接收手机传过来的参数

BufferedInputStream bufferedInputStream = null;

// 此类实现了一个输出流,其中的数据被写入一个字节数组

ByteArrayOutputStream bytesOutputStream = null;

byte [] body = null;

try

{

// BufferedInputStream 输入流

bufferedInputStream = new BufferedInputStream (

request.getInputStream ());

bytesOutputStream = new ByteArrayOutputStream ();

// 写入数据

int ch;

while ((ch = bufferedInputStream.read ()) != -1)

{

bytesOutputStream.write (ch);

}

// 转换为String类型

body = bytesOutputStream.toByteArray ();

}catch (Exception ex)

{

ex.printStackTrace ();

}

finally

{

// 关闭此输入流并释放与该流关联的所有系统资源。

try

{

bytesOutputStream.flush ();

bytesOutputStream.close ();

bufferedInputStream.close ();

}catch (IOException e)

{

e.printStackTrace ();

}

}

return body;

}

public static String getEigthBitsStringFromByte(int b)

{

// if this is a positive number its bits number will be less

// than 8

// so we have to fill it to be a 8 digit binary string

// b=b+100000000(2^8=256) then only get the lower 8 digit

b |= 256; // mark the 9th digit as 1 to make sure the string

// has at

// least 8 digits

String str = Integer.toBinaryString (b);

int len = str.length ();

return str.substring (len - 8,len);

}

public static byte getByteFromEigthBitsString(String str)

{

// if(str.length()!=8)

// throw new Exception("It's not a 8 length string");

byte b;

// check if it's a minus number

if(str.substring (0,1).equals ("1"))

{

// get lower 7 digits original code

str = "0" + str.substring (1);

b = Byte.valueOf (str,2);

// then recover the 8th digit as 1 equal to plus

// 1000000

b |= 128;

}

else

{

b = Byte.valueOf (str,2);

}

return b;

}

/**

* 将一个16字节数组转成128二进制数组

*

* @param b

* @return

*/

public static boolean [] getBinaryFromByte(byte [] b)

{

boolean [] binary = new boolean [b.length * 8 + 1];

String strsum = "";

for (int i = 0;i < b.length;i++ )

{

strsum += getEigthBitsStringFromByte (b [i]);

}

for (int i = 0;i < strsum.length ();i++ )

{

if(strsum.substring (i,i + 1).equalsIgnoreCase ("1"))

{

binary [i + 1] = true;

}

else

{

binary [i + 1] = false;

}

}

return binary;

}

/**

* 将一个128二进制数组转成16字节数组

*

* @param binary

* @return

*/

public static byte [] getByteFromBinary(boolean [] binary)

{

int num = (binary.length - 1) / 8;

if((binary.length - 1) % 8 != 0)

{

num = num + 1;

}

byte [] b = new byte [num];

String s = "";

for (int i = 1;i < binary.length;i++ )

{

if(binary [i])

{

s += "1";

}

else

{

s += "0";

}

}

String tmpstr;

int j = 0;

for (int i = 0;i < s.length ();i = i + 8)

{

tmpstr = s.substring (i,i + 8);

b [j] = getByteFromEigthBitsString (tmpstr);

j = j + 1;

}

return b;

}

/**

* 将一个byte位图转成字符串

*

* @param b

* @return

*/

public static String getStrFromBitMap(byte [] b)

{

String strsum = "";

for (int i = 0;i < b.length;i++ )

{

strsum += getEigthBitsStringFromByte (b [i]);

}

return strsum;

}

/**

* bytes转换成十六进制字符串

*

* @param b

* @return

*/

public static String byte2HexStr(byte [] b)

{

String hs = "";

String stmp = "";

for (int n = 0;n < b.length;n++ )

{

stmp = (Integer.toHexString (b
& 0XFF));

if(stmp.length () == 1)

hs = hs + "0" + stmp;

else

hs = hs + stmp;

}

return hs.toUpperCase ();

}

private static byte uniteBytes(String src0, String src1)

{

byte b0 = Byte.decode ("0x" + src0).byteValue ();

b0 = (byte) (b0 << 4);

byte b1 = Byte.decode ("0x" + src1).byteValue ();

byte ret = (byte) (b0 | b1);

return ret;

}

/**

* 十六进制字符串转换成bytes

*

* @param src

* @return

*/

public static byte [] hexStr2Bytes(String src)

{

int m = 0, n = 0;

int l = src.length () / 2;

byte [] ret = new byte [l];

for (int i = 0;i < l;i++ )

{

m = i * 2 + 1;

n = m + 1;

ret [i] = uniteBytes (src.substring (i * 2,m),

src.substring (m,n));

}

return ret;

}

/**

* 将String转成BCD码

*

* @param s

* @return

*/

public static byte [] StrToBCDBytes(String s)

{

if(s.length () % 2 != 0)

{

s = "0" + s;

}

ByteArrayOutputStream baos = new ByteArrayOutputStream ();

char [] cs = s.toCharArray ();

for (int i = 0;i < cs.length;i += 2)

{

int high = cs [i] - 48;

int low = cs [i + 1] - 48;

baos.write (high << 4 | low);

}

return baos.toByteArray ();

}

/**

* 将BCD码转成int

*

* @param b

* @return

*/

public static int bcdToint(byte [] b)

{

StringBuffer sb = new StringBuffer ();

for (int i = 0;i < b.length;i++ )

{

int h = ((b [i] & 0xff) >> 4) + 48;

sb.append ((char) h);

int l = (b [i] & 0x0f) + 48;

sb.append ((char) l);

}

return Integer.parseInt (sb.toString ());

}

/**

* 输出调试信息

*

* @param str

*/

public static void trace(String str)

{

// System.out.println ("["

// + (new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.S")).format (new Date ())

// + "]>" + str);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: