package com.repair.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.encoders.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @Author: liujun
 * @Description: Aes 加解密算法
 * @Date Create in 上午 9:38$ 2017/12/26 0026$
 * @Modify By:
 */
@Slf4j
public class AesUtils {
    private static String password = "52D04DC20036DBD8";
    /**
     * @Author liujun
     * @Description:
     * @params: * @param content 需要加密的内容
     * @param password  加密密码
     * @Date 上午 9:41 2017/12/26 0026
     */
    public static String encrypt(String content) {

        if(password.length()<16) {
            password = password + "0000000000000000".substring(0, 16-password.length());
        }
        else if(password.length()>16) {
            password = password.substring(0, 16);
        }

        return bytes2HexString(encryptAES(content.getBytes(), password.getBytes()));
    }


    /**
     * @Author liujun
     * @Description:
     * @params: * @param content 待解密内容
     * @param password 解密密钥
     * @Date 上午 9:40 2017/12/26 0026
     */
    public static String decrypt(String content) {
        if(password.length()<16) {
            password = password + "0000000000000000".substring(0, 16-password.length());
        }
        else if(password.length()>16) {
            password = password.substring(0, 16);
        }

        return new String(decryptAES(hexString2Bytes(content), password.getBytes()));
    }

    /**
     * AES 加密
     *
     * @param data 明文
     * @param key  16、24、32 字节秘钥
     * @return 密文
     */
    public static byte[] encryptAES(final byte[] data, final byte[] key) {

        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            byte[] byteContent = data;
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);// 初始化
            byte[] result = cipher.doFinal(byteContent);
            return result; // 加密
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(),e);
        } catch (NoSuchPaddingException e) {
            log.error(e.getMessage(),e);
        } catch (InvalidKeyException e) {
            log.error(e.getMessage(),e);
        } catch (IllegalBlockSizeException e) {
            log.error(e.getMessage(),e);
        } catch (BadPaddingException e) {
            log.error(e.getMessage(),e);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    /**
     * AES 解密
     *
     * @param data 密文
     * @param key  16、24、32 字节秘钥
     * @return 明文
     */
    public static byte[] decryptAES(final byte[] data, final byte[] key) {

        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);// 初始化
            byte[] result = cipher.doFinal(data);
            return result; // 加密
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(),e);
        } catch (NoSuchPaddingException e) {
            log.error(e.getMessage(),e);
        } catch (InvalidKeyException e) {
            log.error(e.getMessage(),e);
        } catch (IllegalBlockSizeException e) {
            log.error(e.getMessage(),e);
        } catch (BadPaddingException e) {
            log.error(e.getMessage(),e);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public static String bytes2HexString(final byte[] bytes) {
        if (bytes == null) return null;
        int len = bytes.length;
        if (len <= 0) return null;
        char[] ret = new char[len << 1];
        for (int i = 0, j = 0; i < len; i++) {
            ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f];
            ret[j++] = hexDigits[bytes[i] & 0x0f];
        }
        return new String(ret);
    }

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

    public static byte[] hexString2Bytes(String hexString) {
        if (isSpace(hexString)) return null;
        int len = hexString.length();
        if (len % 2 != 0) {
            hexString = "0" + hexString;
            len = len + 1;
        }
        char[] hexBytes = hexString.toUpperCase().toCharArray();
        byte[] ret = new byte[len >> 1];
        for (int i = 0; i < len; i += 2) {
            ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1]));
        }
        return ret;
    }

    private static int hex2Dec(final char hexChar) {
        if (hexChar >= '0' && hexChar <= '9') {
            return hexChar - '0';
        } else if (hexChar >= 'A' && hexChar <= 'F') {
            return hexChar - 'A' + 10;
        } else {
            throw new IllegalArgumentException();
        }
    }

    public static byte[] base64Encode(final byte[] input) {
        return Base64.encode(input);
    }

    public static byte[] base64Decode(final byte[] input) {

        return Base64.decode(input);
    }

    private static boolean isSpace(final String s) {
        if (s == null) return true;
        for (int i = 0, len = s.length(); i < len; ++i) {
            if (!Character.isWhitespace(s.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        String s="{\n" +
                "  \"categoryId\": \"72cf28a8789643bbbbb62d08ee91f17e\",\n" +
                "     \"luid\": \"80A036D93CFB\",\n" +
                "     \"type\":\"4\",\n" +
                "     \"userName\":\"13097286670\",\n" +
                "     \"startTime\":\"1682389484000\",\n" +
                "     \"endTime\":\"1684981484000\",\n" +
                "     \"password\":\"A08E87B5E777EBEE2C6EF3262F069D5A\"\n" +
                "}";
        //加密
        String encryptString = AesUtils.encrypt("548903");
        System.out.println("加密后字符串："+encryptString);
        //解密
        String decryptString = AesUtils.decrypt(encryptString);
        System.out.println("解密后字符串："+decryptString);
    }
}
