一: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;
}
}
作者“ERDP技術架構”