java 解析8583 报文

首先 抽象一个类 表示每个域的数据

public class Area {
    private int areaNo;//域序号
    private String areaName;//域名称
    private int leng;//域长度(定长)
    private AreaDataType dataType;//域数据类型
    private AreaLenType lenType;//域长度类型
    private boolean isDynamicLen;//是否是变长
    private String data;//数据
    private int dynamicLen;//变长长度
    private int dynamicLen_2_3;//(变长长度是2/3字节)


    public Area() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Area(int areaNo, String areaName, int leng, AreaDataType dataType, AreaLenType lenType,
            boolean isDynamicLen,int dynamicLen_2_3) {
        super();
        this.areaNo = areaNo;
        this.areaName = areaName;
        this.leng = leng;
        this.dataType = dataType;
        this.lenType = lenType;
        this.isDynamicLen = isDynamicLen;
        this.dynamicLen_2_3 = dynamicLen_2_3;
    }

    public int getDynamicLen_2_3() {
        return dynamicLen_2_3;
    }

    public void setDynamicLen_2_3(int dynamicLen_2_3) {
        this.dynamicLen_2_3 = dynamicLen_2_3;
    }

    public int getDynamicLen() {
        return dynamicLen;
    }

    public void setDynamicLen(int dynamicLen) {
        this.dynamicLen = dynamicLen;
    }

    public boolean isDynamicLen() {
        return isDynamicLen;
    }

    public void setDynamicLen(boolean isDynamicLen) {
        this.isDynamicLen = isDynamicLen;
    }

    public int getAreaNo() {
        return areaNo;
    }
    public void setAreaNo(int areaNo) {
        this.areaNo = areaNo;
    }
    public String getAreaName() {
        return areaName;
    }
    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }
    public int getLeng() {
        return leng;
    }
    public void setLeng(int leng) {
        this.leng = leng;
    }
    public AreaDataType getDataType() {
        return dataType;
    }
    public void setDataType(AreaDataType dataType) {
        this.dataType = dataType;
    }
    public AreaLenType getLenType() {
        return lenType;
    }
    public void setLenType(AreaLenType lenType) {
        this.lenType = lenType;
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Area [areaNo=" + areaNo + ", areaName=" + areaName + ", leng=" + leng + ", dataType=" + dataType
                + ", lenType=" + lenType + ", data=" + data + "]";
    }
    
}

写两个枚举 一个表示该域的数据类型 一个表示数据长度类型

public enum AreaDataType {
    ASCII,
    BCD,
    BINARY
}


public enum AreaLenType {
    ASCII,
    BCD,
    BINARY
}

配置8583域的属性

public class BaoWenConfig {
    
    public  Area area0 = new Area(0, "msgtype", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area1 = new Area(1, "拓展位图", 8, AreaDataType.BINARY, AreaLenType.BCD, false,0);
    public  Area area2 = new Area(2, "主账号", 19, AreaDataType.BCD, AreaLenType.BCD, true,2);
    public  Area area3 = new Area(3, "交易处理码", 6, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area4 = new Area(4, "交易金额", 12, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area11 = new Area(11, "系统跟踪号", 6, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area12 = new Area(12, "受卡发方所在地时间", 6, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area13 = new Area(13, "受卡发方所在地日期", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area14 = new Area(14, "卡有效期", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area15 = new Area(15, "清算日期", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area22 = new Area(22, "服务点输入方式码", 3, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area23 = new Area(23, "卡序列号", 3, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area25 = new Area(25, "服务点条件码", 2, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area26 = new Area(26, "服务点PIN获取码", 2, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area32 = new Area(32, "受理机构标识码", 11, AreaDataType.BCD, AreaLenType.BCD, true,2);
    public  Area area35 = new Area(35, "第二磁道数据", 37, AreaDataType.BCD, AreaLenType.BCD, true,2);
    public  Area area36 = new Area(36, "第三磁道数据", 104, AreaDataType.BCD, AreaLenType.BCD, true,3);
    public  Area area37 = new Area(37, "检索参考号", 12, AreaDataType.ASCII, AreaLenType.BCD, false,0);
    public  Area area38 = new Area(38, "授权标识应答码", 6, AreaDataType.ASCII, AreaLenType.BCD, false,0);
    public  Area area39 = new Area(39, "应答码", 2, AreaDataType.ASCII, AreaLenType.BCD, false,0);
    public  Area area41 = new Area(41, "受卡机终端标识码", 8, AreaDataType.ASCII, AreaLenType.BCD, false,0);
    public  Area area42 = new Area(42, "受卡方标识码", 15, AreaDataType.ASCII, AreaLenType.BCD, false,0);
    public  Area area43 = new Area(43, "商户名称", 40, AreaDataType.ASCII, AreaLenType.ASCII, false,0);
    public  Area area44 = new Area(44, "附加响应数据", 25, AreaDataType.ASCII, AreaLenType.BCD, true,2);
    public  Area area48 = new Area(48, "附加数据-私有", 512, AreaDataType.BCD, AreaLenType.BCD, true,3);
    public  Area area49 = new Area(49, "交易货币代码", 3, AreaDataType.ASCII, AreaLenType.BCD, false,0);
    public  Area area52 = new Area(52, "个人标识码数据", 16, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area53 = new Area(53, "安全控制信息", 16, AreaDataType.BCD, AreaLenType.BCD, false,0);
    public  Area area54 = new Area(54, "实际金额", 32, AreaDataType.ASCII, AreaLenType.BCD, true,3);
    public  Area area55 = new Area(55, "基于PBOC借贷记标准的IC卡数据", 255, AreaDataType.BINARY, AreaLenType.BCD, true,3);
    public  Area area57 = new Area(57, "pos版本", 42, AreaDataType.ASCII, AreaLenType.BCD, true,3);
    public  Area area58 = new Area(58, "基于PBOC电子钱包/存折IC卡标准的交易数据", 100, AreaDataType.BINARY, AreaLenType.BCD, true,3);
    public  Area area60 = new Area(60, "自定义域", 100, AreaDataType.BCD, AreaLenType.BCD, true,3);
    public  Area area61 = new Area(61, "原始信息域", 200, AreaDataType.BCD, AreaLenType.BCD, true,3);
    public  Area area62 = new Area(62, "原始信息域", 200, AreaDataType.BINARY, AreaLenType.BCD, true,3);
    public  Area area63 = new Area(63, "金融网络数据", 200, AreaDataType.ASCII, AreaLenType.BCD, true,3);
    public  Area area64 = new Area(64, "MAC", 8, AreaDataType.ASCII, AreaLenType.BCD, false,0);
    

    public  ArrayList areas = new ArrayList(){/**
         * 
         */
        private static final long serialVersionUID = 4868905912449475521L;
    {
        add(area0);
        add(area1);
        add(area2);
        add(area3);
        add(area4);
        add(area11);
        add(area12);
        add(area13);
        add(area14);
        add(area15);
        add(area22);
        add(area23);
        add(area25);
        add(area26);
        add(area32);
        add(area35);
        add(area36);
        add(area37);
        add(area38);
        add(area39);
        add(area41);
        add(area42);
        add(area43);
        add(area44);
        add(area48);
        add(area49);
        add(area52);
        add(area53);
        add(area54);
        add(area55);
        add(area57);
        add(area58);
        add(area60);
        add(area61);
        add(area62);
        add(area63);
        add(area64);
    }};
    
    
    public Area getAreaWithAreaNo(int no){
        Area result = null;
        for (Area area : areas) {
            if(area.getAreaNo() == no){
                result = area;
                break;
            }
        }
        return result;
    }
    
    
    
}

处理8583报文的主要类

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Deal8583 {
    private static BASE64Encoder encoder = new BASE64Encoder();
    private static BASE64Decoder decoder = new BASE64Decoder();

    public static String byte2hex(byte[] b) // 二进制转字符串
    {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            
            if (stmp.length() == 1){
                hs = hs + "0" + stmp;
            }
            else{
                hs = hs + stmp;
            }
        }
        return hs;
    }
    
    public static byte[] hex2byte(String str) { // 字符串转二进制
        if (str == null){
            return null;
        }
        str = str.trim();
        int len = str.length();
        if (len == 0 || len % 2 == 1){
            return null;
        }
        byte[] b = new byte[len / 2];
        try {for (int i = 0; i < str.length(); i += 2) {
            b[i / 2] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
        }
        return b;
        } catch (Exception e) {
            return null;
        }
    }

    public static String asciiToString(String value)  
    {  
        StringBuffer sbu = new StringBuffer();  
        String[] chars = value.split(",");  
        for (int i = 0; i < chars.length; i++) {  
            sbu.append((char) Integer.parseInt(chars[i]));  
        }  
        return sbu.toString();  
    }
    
    public static String stringToAscii(String value)  
    {  
        StringBuffer sbu = new StringBuffer();  
        char[] chars = value.toCharArray();   
        for (int i = 0; i < chars.length; i++) {  
            if(i != chars.length - 1)  
            {  
                sbu.append((int)chars[i]).append(",");  
            }  
            else {  
                sbu.append((int)chars[i]);  
            }  
        }  
        return sbu.toString();  
    }  
    
    public static String byteToASCString(byte[] bArray){
        String strASC="";
        String strTemp="";
        for(int i=0;i> 4) + 48;
            sb.append((char) h);
            int l = (b[i] & 0x0f) + 48;
            sb.append((char) l);
        }
        return Integer.parseInt(sb.toString());
    }

    // 将byte数组bRefArr转为一个整数,字节数组的低位是整型的低字节位
    public static int byteToInt(byte[] bRefArr) {
        int iOutcome = 0;
        byte bLoop;

        for (int i = 0; i < bRefArr.length; i++) {
            bLoop = bRefArr[i];
            iOutcome += (bLoop & 0xFF) << (8 * i);
        }
        return iOutcome;
    }
    
    /**
     * 向服务器 发送8583报文
     * 
     * @param send8583Str 发送给服务器的报文
     * 
     * @param host 主机地址IP
     * 
     * @param port 端口号
     * 
     * @return 返回的数据
     * */
    public static String send8583(String send8583Str,String host,int port) throws Exception{
        //客户端请求与本机在20011端口建立TCP连接 
        Socket client = new Socket(host, port);  
        client.setSoTimeout(70000);             
        //获取Socket的输出流,用来发送数据到服务端                  
        PrintStream out = new PrintStream(client.getOutputStream());          
        //获取Socket的输入流,用来接收从服务端发送过来的数据 
        InputStream buf =  client.getInputStream();  
        String str = "mpos-"+send8583Str;  
        //发送数据到服务端   
        out.println(str);  
        try{  
            byte[] b = new byte[1024];
            int rc=0;
            int c = 0;
            while( (rc = buf.read(b, c, 1024) )>=0){
                c = buf.read(b, 0, rc);
            }
            String returnStr = byte2hex(b);
            String string = returnStr;
            String str16 = string.substring(0, 4);
            int leng = Integer.parseInt(str16,16);
            String result = string.substring(0, leng*2 + 4);
            if (client!=null) {
                client.close();
            }
            return result;
        }catch(Exception e){ 
            e.printStackTrace();
            System.out.println("Time out, No response");  
        }
        if (client!=null) {
            client.close();
        }
       return null;
    }
    
    public static String bitmapHex2Binary(String bitmap){
        String bitMapStr =  bitmap;
        if (bitMapStr == null || bitMapStr.length() % 2 != 0)
            return null;
        String bString = "", tmp;
        for (int i = 0; i < bitMapStr.length(); i++)
        {
            tmp = "0000"
                    + Integer.toBinaryString(Integer.parseInt(bitMapStr
                            .substring(i, i + 1), 16));
            bString += tmp.substring(tmp.length() - 4);
        }
        return bString;
    }
    
    public static String getBitMapStr(String str8583){
        return str8583.substring(30, 46);
    }
    
    /**
     * 获得报文的位图数组
     * 
     * */
    public static ArrayList getBitMap(String bitMapStr){
        ArrayList bitMaps = new ArrayList();
        if (bitMapStr == null || bitMapStr.length() % 2 != 0)
            return null;
        String bString = "", tmp;
        for (int i = 0; i < bitMapStr.length(); i++)
        {
            tmp = "0000"
                    + Integer.toBinaryString(Integer.parseInt(bitMapStr
                            .substring(i, i + 1), 16));
            bString += tmp.substring(tmp.length() - 4);
        }
        for(int i = 0 ; i < bString.length() ; i ++){
            char c = bString.charAt(i);
            int flag = Integer.parseInt(String.format("%c", c));
            if (flag==1) {
                bitMaps.add(i+1);
            }
        }
        return bitMaps;
    }

    /**
     * 解析8583报文
     * @param str8583 8583报文
     * @param resultMap 存放8583全部解析后的Map
     * @return 填充完成的域数组集合
     * 
     * */
    public static ArrayList jiexi8583(String str8583,HashMap resultMap){
        
        //报文总长
        int currentIndex = 0;
        String lenStr = str8583.substring(currentIndex, 4);
        resultMap.put("LEN", lenStr);
        currentIndex += lenStr.length();
        
        //tpdu
        String TPDUStr = str8583.substring(currentIndex, currentIndex+10);
        resultMap.put("TPDU", TPDUStr);
        currentIndex += TPDUStr.length();
        
        //msghead
        String MSGHEADStr = str8583.substring(currentIndex,currentIndex+12);
        resultMap.put("MSGHEAD", MSGHEADStr);
        currentIndex += MSGHEADStr.length();
        
        //报文type
        String TYPEStr = str8583.substring(currentIndex, currentIndex+4);
        resultMap.put("TYPE", TYPEStr);
        currentIndex += TYPEStr.length();
        
        //位图
        String BITMAPStr = str8583.substring(currentIndex,currentIndex+16); 
        resultMap.put("BITMAP", BITMAPStr);
        currentIndex += BITMAPStr.length();
        
        //位图数组
        ArrayList bitmaps = getBitMap(BITMAPStr);
        
        //报文配置
        BaoWenConfig config = new BaoWenConfig();
        //根据位图找到报文对应的域
        ArrayList areas = new ArrayList();
        for (Integer areaNo : bitmaps) {
            areas.add(config.getAreaWithAreaNo(areaNo));
        }
        //为每个域填充信息
        for (Area area : areas) {
            String areaDataStr = null;//用来存放该域的数据
            if( area.isDynamicLen()){//如果是变长的话
                if(area.getDataType()==AreaDataType.BCD && area.getLenType() == AreaLenType.BCD){
                    String dylenStr = null;
                    int useLen = 0;
                    if (area.getDynamicLen_2_3() == 2) {
                        dylenStr = str8583.substring(currentIndex,currentIndex+2);
                        currentIndex += 2;
                        int dataLen = Integer.parseInt(dylenStr);
                        if (dataLen %2 ==0) {
                            useLen = dataLen; 
                        }else{
                            useLen = dataLen + 1;
                        }
                    }else if(area.getDynamicLen_2_3() == 3){
                        dylenStr = str8583.substring(currentIndex,currentIndex+4);
                        currentIndex += 4;
                        int dataLen = Integer.parseInt(dylenStr);
                        if (dataLen %2 ==0) {
                            useLen = dataLen; 
                        }else{
                            useLen = dataLen + 1;
                        }
                    }
                    
                    areaDataStr = str8583.substring(currentIndex, currentIndex+useLen);
                    currentIndex += areaDataStr.length();
                    resultMap.put(String.format("%d", area.getAreaNo()), areaDataStr);
                    area.setLeng(Integer.parseInt(dylenStr));
                    
                }else if(area.getDataType()==AreaDataType.ASCII && area.getLenType() == AreaLenType.BCD){
                    String dylenStr = str8583.substring(currentIndex,currentIndex+4);
                    currentIndex += 4;
                    areaDataStr = str8583.substring(currentIndex, currentIndex+Integer.parseInt(dylenStr)*2);
                    currentIndex +=areaDataStr.length();
                    resultMap.put(String.format("%d", area.getAreaNo()), areaDataStr);
                    
                    area.setLeng(Integer.parseInt(dylenStr));
                    
                }else if(area.getDataType()==AreaDataType.BINARY && area.getLenType() == AreaLenType.BCD){
                    String dylenStr = str8583.substring(currentIndex,currentIndex+4);
                    currentIndex += 4;
                    areaDataStr = str8583.substring(currentIndex, currentIndex+Integer.parseInt(dylenStr)*2);
                    currentIndex +=areaDataStr.length();
                    resultMap.put(String.format("%d", area.getAreaNo()), areaDataStr);
                    area.setLeng(Integer.parseInt(dylenStr));
                }
            }else{//如果是固定长度
                if(area.getDataType()==AreaDataType.BCD && area.getLenType() == AreaLenType.BCD){
                    areaDataStr = str8583.substring(currentIndex,currentIndex+area.getLeng()); 
                    resultMap.put(String.format("%d", area.getAreaNo()) , areaDataStr);
                    currentIndex += areaDataStr.length() %2 ==0 ?areaDataStr.length():areaDataStr.length()+1 ;
                }else if(area.getDataType()==AreaDataType.ASCII && area.getLenType() == AreaLenType.BCD){
                    areaDataStr = str8583.substring(currentIndex,currentIndex+area.getLeng() * 2); 
                    resultMap.put(String.format("%d", area.getAreaNo()) , areaDataStr);
                    currentIndex += areaDataStr.length();
                }
            }
            //存放到该域
            area.setData(areaDataStr);
        }
        return areas;
    }
    
    public static void main(String[] args) throws Exception {
        String baowen = "012760000300006022000000000200702406C020C09A111662596543203269930000000000008890000006972212071000010012376259654320326993D2212201000007820000003130303030303132333034343532303438313230303031313536EF7F40420E3741FE260000000000000001649F26083AE8A83B8A54F8739F2701809F101307020103A00000010A0100000000008D9318249F3704E97798B59F3602017D950500000000009A031702219C01009F02060000008890005F2A02015682027C009F1A0201569F03060000000000009F3303E0E1C89F34030200009F3501229F1E0838373937303835378408A0000003330101029F090200309F4104000006979F6310303130353030303000000000000000000014220000020006013246373437303042";
        HashMap resultMap = new HashMap();
        ArrayList areas = jiexi8583(baowen,resultMap);
        System.out.println(resultMap);
        for (Area area : areas) {
            System.out.println(area);
        }
    }
}

你可能感兴趣的:(java 解析8583 报文)