package tech.glinfo.enbao.common.utils;

import org.apache.commons.lang.StringUtils;

import java.io.*;

/**
 * Created by Li.shangzhi on 17/1/10.
 */
public class ByteUtils {

    private static final String DEFAULTSN = "0000000000000000000000000000";
    private static final String DEFAULTASCII = "00000000000000";


    /**
     * 读取文件，返回字节数组
     * @param file
     * @return
     */
    public static byte[] getBinFromFile(File file) {
        InputStream is = null;
        ByteArrayOutputStream bos = null;
        byte[] rtn = null;
        try {
            is = new FileInputStream(file);
            byte[] buffer = new byte[1024];

            int len = 0;
            bos = new ByteArrayOutputStream();
            while ((len = is.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            rtn = bos.toByteArray();
        } catch (IOException e) {
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                }
            }
        }


        return rtn;
    }

    public static byte[] createBufferFromString(String cmdParams, boolean zeroFlag) {
        byte[] abytBuffer = null;
        if(StringUtils.isBlank(cmdParams)) {
            return null;
        }
        try {
            byte[] bytes = cmdParams.getBytes("utf8");

            byte[] bytes1 = int2Byte(bytes.length + (zeroFlag?1:0));
            int newLength = zeroFlag ? 4 + bytes.length + 1 : 4 + bytes.length;
            abytBuffer = new byte[newLength];
            System.arraycopy(bytes1, 0, abytBuffer, 0, 4);
            System.arraycopy(bytes, 0, abytBuffer, 4, bytes.length);
            if(zeroFlag) {
                abytBuffer[4 + bytes.length] = 0;
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return abytBuffer;
    }

    public static byte[] appendBinaryData(byte[] bt1, byte[] bt2) {
        byte[] bt3 = new byte[bt1.length+4+bt2.length];
        byte[] bt4 = int2Byte(bt2.length);
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt4, 0, bt3, bt1.length, 4);
        System.arraycopy(bt2, 0, bt3, bt1.length + 4, bt2.length);
        return bt3;
    }

    public static byte[] int2Byte(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        return b;
    }

    /**
     * byte数组转换成16进制字符串
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
            }
            stringBuilder.append(hv);
            stringBuilder.append(0);
        }
        return stringBuilder.toString();
    }

    public static String bytes2HexString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 字符串转十六进制
     *
     * @param s
     * @return
     */
    public static String strToHex(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }

    /**
     * 16进制转换成为string类型字符串
     *
     * @param s
     * @return
     */
    public static String hexToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }


    /**
     * 计算和校验校验码
     *
     * @param data
     * @return
     */
    public static String makeCheckNum(String data) {
        if (data == null || data.equals("")) {
            return "";
        }
        int total = 0;
        int len = data.length();
        int num = 0;
        while (num < len) {
            String s = data.substring(num, num + 2);
//            System.out.println(s);
            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
        /**
         * 用65536求余最大是65535，即16进制的FFFF
         */
        int mod = total % 65536;
//        String hex = Integer.toHexString(mod);
//        len = hex.length();
        // 如果不够校验位的长度，补0,这里用的是两位校验
        String hex = intToHex(mod);
        while (hex.length() < 4) {
            hex = "0" + hex;
        }
        return hex;
    }

    /**
     * 校验校验码
     *
     * @param data
     * @param checkNum
     * @return
     */
    public static boolean checkNum(String data, String checkNum) {
        String makeCheckNum = makeCheckNum(data);
        return makeCheckNum.equals(checkNum);
    }

    private static String intToHex(int n) {
        if(n == 0) {
            return "00";
        }
        //StringBuffer s = new StringBuffer();
        StringBuilder sb = new StringBuilder(8);
        String a;
        char[] b = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        while (n != 0) {
            sb = sb.append(b[n % 16]);
            n = n / 16;
        }
        a = sb.reverse().toString();
        return a;
    }

    public static String int2Hex(int n) {
        String s = intToHex(n);
        int i = s.length() % 2;
        StringBuilder sb = new StringBuilder();
        while (i > 0) {
            sb.append("0");
            i--;
        }

        return sb.append(s).toString();
    }

    public static String int2Hex(int n, int length) {
//        if(n == 0) {
//            return "00";
//        }
        String s = intToHex(n);
        int i = length - s.length();
        StringBuilder sb = new StringBuilder();
        while (i > 0) {
            sb.append("0");
            i--;
        }
        sb.append(s);
//        System.out.println(n+"="+sb.toString());
        return sb.toString();
    }


    public static String hexstr2Hex(String msg) {
        StringBuffer sb = new StringBuffer();
        int length = msg.length();
        int i = 0;
        while (i < length) {
            sb.append(msg.substring(i, i + 2)).append(" ");
            i += 2;
        }

        return sb.toString();
    }

    /**
     * 将十六进制的字符串转换成字节数组
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStrToBinaryStr(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return null;
        }
        hexString = hexString.replaceAll(" ", "");
        int len = hexString.length();
        int index = 0;
        byte[] bytes = new byte[len / 2];
        while (index < len) {
            String sub = hexString.substring(index, index + 2);
            bytes[index / 2] = (byte) Integer.parseInt(sub, 16);
            index += 2;
        }
        return bytes;
    }

    /**
     * ASCII码转十六进制
     * @param input
     * @return
     */
    public static String asciiToHex(String input) {
        if(DEFAULTASCII.equals(input)) {
            return DEFAULTSN;
        }
        StringBuffer sb = new StringBuffer();
        byte[] bytes = input.getBytes();
        for (byte b : bytes) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                sb.append(0);
            }
            sb.append(hv);
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 十六进制转ASCII码
     * @param hex
     * @return
     */
    public static String hexToAscii(String hex) {
        if(DEFAULTSN.equals(hex)) {
            return DEFAULTASCII;
        }
        StringBuffer sb = new StringBuffer();
        int length = hex.length();
        for( int i=0; i<length; i+=2 ){
            //grab the hex in pairs
            String output = hex.substring(i, (i + 2));
            //convert hex to decimal
            int decimal = Integer.parseInt(output, 16);
            //convert the decimal to character
            sb.append((char)decimal);
        }
        return sb.toString();
    }

    /**
     * 十六进制转int字符串
     * @param hex
     * @return
     */
    public static String signHex2IntString(String hex) {
        int ret = Integer.parseInt(hex, 16);
        if(hex.length() == 2) {//2位
            ret = ((ret & 0x80) > 0) ? (ret - 0x100) : (ret);
        } else if(hex.length() == 4) {//4位
            ret = ((ret & 0x8000) > 0) ? (ret - 0x10000) : (ret);
        }
        return String.valueOf(ret);
    }

    /**
     * 有符号十进制字符串转十六进制
     * @param intstr 十进制字符串
     * @param length 多少位，一般是2位，表示范围-128~127
     * @return
     */
    public static String signInt2HexString(String intstr, int length) {
        String hex = Integer.toHexString(Integer.parseInt(intstr));
        int hl = hex.length();
        if(hl < length) {
            while (hl < length) {
                hex = "0" + hex;
                hl++;
            }
            return hex;
        } else {
            return hex.substring(hl - length).toUpperCase();
        }
    }

    public static byte[] byteCopy(byte[] bt1, byte[] bt2) {
        byte[] bt3 = new byte[bt1.length+bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }

    public static void main(String[] args) {
//        System.out.println(strToHex("134A"));
//        System.out.println(hexToString("A5 7E 00 00 00 00 00 00 00 00 00 00 03 02 01 04 05 06 07 08 00 00 01 81 01 00 00 A7 E7 A5 0D "));
//        System.out.println(int2Hex(256));

//        System.out.println(makeCheckNum("030201040506070800000000000000000000000001920100"));
//        System.out.println(strToHex("7654321"));

        String content = "0100000064123133343630373430353034313739313138390000000000000000";
        String feestr = content.substring(2, 10);
        String codeLen = content.substring(10, 12);
        String codeHex = content.substring(12, 60);
        String authCode = ByteUtils.hexToAscii(codeHex);

        System.out.println(codeHex);
        System.out.println(authCode);
        System.out.println(int2Hex(4400));
        System.out.println(strToHex("4400"));

        System.out.println(signHex2IntString("FE"));
        System.out.println(signHex2IntString("ff00"));
        System.out.println(Integer.toHexString(-256));
        System.out.println(signInt2HexString("20", 2));

        System.out.println(hexToString("343431373933336638663330"));
        System.out.println(hexToString("54502D4C494E4B5F393332"));
        System.out.println(hexToString("3031384542323132353132303031"));
        System.out.println(hexToString("3031414542323132323030323030"));
//2B0218643434313739333366386633300E30313845423231323531323030310C54502D4C494E4B5F39333244
    }
}