2025-02-15

一: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技術架構”

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *