8583

来源:互联网 发布:测试工程师 知乎 编辑:程序博客网 时间:2024/06/05 10:33
package com.bestpay.paycenter.entry.http.controller.ccb.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.Map;
import java.util.TreeMap;
import java.util.Arrays;
/**
 * Created with IntelliJ IDEA.
 * User: chengerxiang
 * 测试建设银行签到接口
 * Date: 14-1-8
 * Time: 下午5:20
 */
@Controller
@Slf4j
public class Test8583 {
    public static String encoding = "UTF-8";

    /**
     * 封装报文
     * @return
     */
    public static void init() {
        log.info("进入Test8583 init方法,封装请求报文-----");
        byte[] parm = null;
        //TPDU长度5字节:ID(H60)+目的地址(N2)+源地址(N2)
        //6000060000
        //byte[] tpdu = hexStringToByte("6000060000");
        byte[] tpdu = {0x60,0x00,0x06,0x00,0x00};
        //报文头(长度12字节):应用类别N2+软件版本号N2+终端状态N1+处理要求N1+保留使用N6
        String packageHead = "60" + "01" + "1" + "1" + "      ";
        //加密信息:报文长度A3+算法标识A1+商户号A15+终端号A8+交易标识A10+响应码A2+保留A2
        String encryptedMessages = "135" + "0" + "105110070110485" + "00015723" + "0800179900" + "  " + "FF";
        //应用数据
        String messageType = "0800";//域名-消息类型 属性-n4 类型:BCD 请求:0800 响应:0810

        byte[] bitMap = get8BitByteFromStr(getBitMap()); //域名-位图 属性-b64 类型:binary
        String sysno = "179900";//POS终端交易流水(受卡方终端跟踪号)
        String flagNo = "00015723";//(终端代码)受卡机终端标识码
        String merchantNo = "105110070110485";//(商户号)受卡方标识码
        String originalMessage60 = "01100123456001";//长度+交易类型码+批次号+网络管理信息码
        String originalMessage63 = "077000";//长度+操作员代码+终端版本号+软件交易类型
        for(int i = 0;i<73;i++){
            originalMessage63 += " ";
        }
        originalMessage63 +="1";
        //parm = arrayApend(arrayApend((tpdu + packageHead + encryptedMessages + messageType).getBytes(),bitMap),(sysno + flagNo + merchantNo + originalMessage60 + originalMessage63).getBytes());
       // parm = arrayApend(arrayApend(arrayApend(tpdu,(packageHead + encryptedMessages + messageType).getBytes()),bitMap),(sysno + flagNo + merchantNo + originalMessage60 + originalMessage63).getBytes());
        byte[] b1 = arrayApend(tpdu,(packageHead + encryptedMessages + messageType).getBytes());
        byte[] b2 = arrayApend(b1,bitMap);
        parm = arrayApend(b2,(sysno + flagNo + merchantNo + originalMessage60 + originalMessage63).getBytes());
        log.info("请求报文的长度为:"+parm.length);
        sendData(parm);
    }

    /**
     * 发送请求
     */
    public static void sendData(byte[] pram) {
        log.info("进入发送请求方法-----");
       try {
           log.info("创建请求ip地址socket");
           log.info("正在连接……");
            Socket socket = new Socket("172.16.56.26", 12009);
            log.info("从socket获取流对象");
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            DataInputStream dif = new DataInputStream(socket.getInputStream());
            log.info("通过流发送数据");
            //写出数据
            out.write(pram);
            out.flush();
            socket.shutdownOutput();
            log.info("清空输出流");
            //out.close();
            String strReader = null;
            StringBuffer strReaderBuffer = new StringBuffer();
            //读取服务器返回的数据
            boolean isTrue = true;
            byte[] content8583 = new byte[1024];
            int num = dif.read(content8583);
            log.info("响应报文字节总数:" + num);
            /*int acceptByte = -1;
            while((acceptByte = dif.read()) != -1){
                int i = 0;
                content8583[i] = (byte)acceptByte;
                i++;
            }*/
            dif.close();
            socket.close();
            analyze8583(content8583);
        } catch (IOException e) {
           log.info("socket创建失败!"+e);
        }
    }

    /**
     * 构建二进制表示位图字符串
     *
     * @return
     */
    public static String getBitMap() {
        //签到请求域11、41、42、60、63
        return "00000000" + "00100000" + "00000000" + "00000000" + "00000000" + "11000000" + "00000000" + "00010010";
    }

    /**
     * 二进制字符串转换成int,再转换成字节
     */
    public static void strTobyte(String s) {
        for (int i = 0; i < s.length(); i += 8) {
            String subStr = s.substring(i, (i + 8) - 1);
            //System.out.println(subStr);
            byte b = (byte) Integer.parseInt(subStr);
        }
    }

    /**
     * 字符串转换成字节数组
     *
     * @param str
     * @return
     */
    public static byte[] stringToByte(String str) {
        return str.getBytes();
    }

    /**
     * 字节数组转换成16进制表示的字符串
     *
     * @param b
     * @return
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString().toUpperCase();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n = 256 + n;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    /*
     * 把16进制字符串转换成字节数组 @param hex @return
     */
    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }

    private static byte toByte(char c) {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }


    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};

    public static String strToAscii(String str) {
        return null;
    }

    /**
     * 字符串转换成ASCII码
     *
     * @param value
     * @return
     */
    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();
    }


    /**
     * 字符串转换成BCD码(8421)
     *
     * @param str
     * @return
     */
    public static String strToBcd(String str) {
        String rex = "\\d+";
        if (!str.matches(rex)) {
            log.info("参数必须是数字字符或数字字符串");
            return null;
        }
        char[] str_char = str.toCharArray();
        StringBuffer strBuffer = new StringBuffer();
        String temp = null;
        for (int i = 0; i < str_char.length; i++) {
            switch (str_char[i]) {
                case '0':
                    temp = "0000";
                    strBuffer.append(temp);
                    break;
                case '1':
                    temp = "0001";
                    strBuffer.append(temp);
                    break;
                case '2':
                    temp = "0010";
                    strBuffer.append(temp);
                    break;
                case '3':
                    temp = "0011";
                    strBuffer.append(temp);
                    break;
                case '4':
                    temp = "0100";
                    strBuffer.append(temp);
                    break;
                case '5':
                    temp = "0101";
                    strBuffer.append(temp);
                    break;
                case '6':
                    temp = "0110";
                    strBuffer.append(temp);
                    break;
                case '7':
                    temp = "0111";
                    strBuffer.append(temp);
                    break;
                case '8':
                    temp = "1000";
                    strBuffer.append(temp);
                    break;
                case '9':
                    temp = "1001";
                    strBuffer.append(temp);
                    break;
                default:
                    log.info("BCD编码失败");
                    return null;
            }
        }
        return strBuffer.toString();
    }

    public static String strToHex(String str) {
        return null;
    }

    /**
     * 位图操作
     * <p/>
     * 把64位01字符串转化成8位图的字节数组
     */
    public static byte[] get8BitByteFromStr(String str_64) {
        byte[] bit8 = new byte[8];
        try {
            if (str_64 == null || str_64.length() != 64) {
                return null;
            }
            // 64域位图二进制字符串转8位16进制
            byte[] tmp = str_64.getBytes(encoding);
            int weight;//权重
            byte[] strout = new byte[64];
            int i, j, w = 0;
            for (i = 0; i < 8; i++) {
                weight = 0x0080;
                for (j = 0; j < 8; j++) {
                    strout[i] += ((tmp[w]) - '0') * weight;
                    weight /= 2;
                    w++;
                }
                bit8[i] = strout[i];
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return bit8;
    }

    /**
     * 解析8583报文
     *
     * @param content8583
     */
    @SuppressWarnings("rawtypes")
    public static Map analyze8583(byte[] content8583) {
        log.info("------------------------------解析报文----------------------------------");
        TreeMap filedMap = new TreeMap();
        try {
            // 取位图
            byte[] bitMap8byte = new byte[8];
            System.arraycopy(content8583,62,bitMap8byte,0,8);
            // 8位图转2进制位图64位字符串
            String bitMap64Str = get8BitMapStr(bitMap8byte);

            //记录当前位置,从位图后开始遍历取值
            int pos = 8;
            // 遍历64位图,取值。注意,第0位是位图,从1开始遍历
            StringBuffer bitMapNo = new StringBuffer("响应报文域分别是:");
            for (int i = 0; i < bitMap64Str.length(); i++) {

                if (bitMap64Str.charAt(i) == '1') {
                    // 获取域定义信息
                    bitMapNo.append((i+1) + "|");

                   /* boolean isFixLen = true;//是否定长判断

                    if (defLen.startsWith("VAR")) {//变长域
                        isFixLen = false;
                        defLen = defLen.substring(3);//获取VAR2后面的2
                    }
                    // 截取该域信息
                    if (!isFixLen) {//变长域
                        int defLen1 = Integer.valueOf(defLen);//VAR2后面的2
                        String realLen1 = new String(content8583, pos, defLen1, encoding);//报文中实际记录域长,例如16,023
                        int realAllLen = defLen1 + Integer.valueOf(realLen1);//该字段总长度(包括长度值占的长度)
                        byte[] filedValueByte = new byte[Integer.valueOf(realLen1)];
                        System.arraycopy(content8583, pos + defLen1, filedValueByte, 0, filedValueByte.length);
                        filedValue = new String(filedValueByte, encoding);
                        pos += realAllLen;//记录当前位置
                    } else {//定长域
                        int defLen2 = Integer.valueOf(defLen);//长度值占的位数
                        filedValue = new String(content8583, pos, defLen2, encoding);
                        pos += defLen2;//记录当前位置
                    }
                    filedMap.put(filedName, filedValue);*/
                }
            }//end for
            log.info(bitMapNo.toString());
            //本例连接签到接口,所有数据都写死
            //第18个字节是报文长度,即应用数据长度
            byte[] tpduID = new byte[5];
            System.arraycopy(content8583, 0, tpduID, 0, 5);
            log.info("tpdu为:" + new String(tpduID));

            byte[] packegHead = new byte[12];
            System.arraycopy(content8583, 5, packegHead, 0, 12);
            log.info("报文头:" + new String(packegHead));


            byte[] appType = new byte[2];
            System.arraycopy(content8583, 5, appType, 0, 2);
            log.info("应用类别:" + new String(appType));

            byte[] messageLength = new byte[3];
            System.arraycopy(content8583, 17, messageLength, 0, 3);
            log.info("报文长度为:" + new String(messageLength));

            byte[] flag = new byte[1];
            System.arraycopy(content8583, 20, flag, 0, 1);
            log.info("算法标识:" + new String(flag));

            byte[] merchantNo = new byte[15];
            System.arraycopy(content8583, 21, merchantNo, 0, 15);
            log.info("商户号:" + new String(merchantNo));

            byte[] terminalNo = new byte[8];
            System.arraycopy(content8583, 36, terminalNo, 0, 8);
            log.info("终端号:" + new String(terminalNo));

            byte[] tradeNo = new byte[10];
            System.arraycopy(content8583, 44, tradeNo, 0, 10);
            log.info("交易标识:" + new String(tradeNo));

            byte[] resNo = new byte[2];
            System.arraycopy(content8583, 54, resNo, 0, 2);
            log.info("响应码:"+ new String(resNo));

        } catch (Exception e) {
            log.info("解析响应报文错误!"+e);
            e.printStackTrace();
        }
        return filedMap;
    }

    /**
     * 位图操作
     * 把8个字节位图的字节数组转化成64位二进制的字符串表示
     *
     * @param
     * @return
     */
    public static String get8BitMapStr(byte[] bitMap8) {
        String bitMap64 = "";
        // 8字节位图转2进制位图64位字符串
        for (int i = 0; i < bitMap8.length; i++) {
            int bc = bitMap8[i];
            bc = (bc < 0) ? (bc + 256) : bc;
            String bitnaryStr = Integer.toBinaryString(bc);//二进制字符串
            // 左补零,保证是8位
            String rightBitnaryStr = strCopy("0", Math.abs(8 - bitnaryStr.length())) + bitnaryStr;//位图二进制的字符串表示
            // 先去除多余的零,然后组装64域二进制字符串
            bitMap64 += rightBitnaryStr;
        }
        log.info("解析位图的二进制字符串表示:");
        log.info(bitMap64);
        return bitMap64;
    }

    /**
     * 复制字符
     *
     * @param str
     * @param count
     * @return
     */
    public static String strCopy(String str, int count) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            sb.append(str);
        }
        return sb.toString();
    }

    /**
     * 返回a和b的组合,实现累加功能
     *
     * @param a
     * @param b
     * @return
     */
    public static byte[] arrayApend(byte[] a, byte[] b) {
        int a_len = (a == null ? 0 : a.length);
        int b_len = (b == null ? 0 : b.length);
        byte[] c = new byte[a_len + b_len];
        if (a_len == 0 && b_len == 0) {
            return null;
        } else if (a_len == 0) {
            System.arraycopy(b, 0, c, 0, b.length);
        } else if (b_len == 0) {
            System.arraycopy(a, 0, c, 0, a.length);
        } else {
            System.arraycopy(a, 0, c, 0, a.length);
            System.arraycopy(b, 0, c, a.length, b.length);
        }
        return c;
    }

    /**
     * int类型转换成byte[]
     * @param num
     *int数
    * @return byte[]
    */
    public static byte[] intToBytes(int num) {
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            b[i] = (byte) (num >>> (24 - i * 8));
        }
        return b;
    }

    /**
     * 将4字节的byte数组转成int值
     * @param b
     * @return
     */
    public static int byteArray2int(byte[] b){
        byte[] a = new byte[4];
        int i = a.length - 1,j = b.length - 1;
        for (; i >= 0 ; i--,j--) {//从b的尾部(即int值的低位)开始copy数据
            if(j >= 0)
                a[i] = b[j];
            else
                a[i] = 0;//如果b.length不足4,则将高位补0
        }
        int v0 = (a[0] & 0xff) << 24;//&0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
        int v1 = (a[1] & 0xff) << 16;
        int v2 = (a[2] & 0xff) << 8;
        int v3 = (a[3] & 0xff) ;
        return v0 + v1 + v2 + v3;
    }

    public static void main(String[] args){
        /*String s = "303030383030204631202020C8A15B5DEFBFBDEFBFBDC8ABEFBFBDEFBFBDEFBFBDEFBFBDCAA7EFBFBDEFBFBD21";
        try{
            //System.out.println(new String(hexStringToByte(s),"gb2312"));
            byte[] bytes = s.getBytes("gbk");
            //System.out.println(new String(bytes,"gbk"));
            System.out.println(new String(hexStringToByte(new String(bytes,"utf-8")),"gbk"));
        }catch (Exception e){

        }*/

        String s = "6000060000";
        byte[] b1 = {0x60,0x00,0x06,0x00,0x00};
        byte[] tpdu = hexStringToByte("6000060000");
        System.out.println(Arrays.equals(b1,tpdu));
        System.out.println(byteArrayToHexString(b1));
        System.out.println(byteArrayToHexString(tpdu));
        String originalMessage63 = "077000";//长度+操作员代码+终端版本号+软件交易类型
        for(int i = 0;i<73;i++){
            originalMessage63 += " ";
        }
        originalMessage63 +="1";
        System.out.println(originalMessage63);
        System.out.println(originalMessage63.length());

    }
}

0 0
原创粉丝点击