package com.rf.psychological.security;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Set;

/**
 * @author zzf
 * @description:
 * @date 2021/7/29 9:16
 */
public class DESede {
    private DESede() {

    }

    /**
     * 加解密使用的字符集
     */
    private static final String DESEDE_CHARSET_NAME = "UTF-8";

    /**
     * 加密算法
     */
    private static final String DESEDE = "DESede";

    /**
     * 算法的转换名称
     */
    private static final String DES_CBC = "DESede/CBC/PKCS5Padding";

    /**
     * 默认密钥
     */
    public static final String DEFAULT_KEY = "240262447423713749922240";

    /**
     * 默认向量值
     */
    public static String DEFAULT_DESEDE_IV = "12345678";

    /**
     * 使用3Des算法进行明文加密
     *
     * @param key    24个字符的密钥(3个des密钥)
     * @param ivByte 8字符的随机向量
     * @param value  需要进行加密的原明文字节数组
     * @return 加密后的密文字节数组，如果加密失败，返回null
     */
    public static byte[] encrypt(byte[] key, byte[] ivByte, byte[] value) {
        try {

            SecureRandom sr = new SecureRandom();
            SecretKey securekey = new SecretKeySpec(key, DESEDE);
            IvParameterSpec iv = new IvParameterSpec(ivByte);
            Cipher cipher = Cipher.getInstance(DES_CBC);
            cipher.init(Cipher.ENCRYPT_MODE, securekey, iv, sr);

            return cipher.doFinal(value);

        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 使用3Des算法进行密文解密
     *
     * @param key    24个字符的密钥(3个des密钥)
     * @param ivByte 8字符的随机向量
     * @param value  需要进行解密的密文字节数组
     * @return 返回解密后的明文字节数组, 如果解密失败，返回null
     */
    public static byte[] decrypt(byte[] key, byte[] ivByte, byte[] value) {
        try {

            SecureRandom sr = new SecureRandom();
            SecretKey securekey = new SecretKeySpec(key, DESEDE);
            IvParameterSpec iv = new IvParameterSpec(ivByte);
            Cipher cipher = Cipher.getInstance(DES_CBC);
            cipher.init(Cipher.DECRYPT_MODE, securekey, iv, sr);

            return cipher.doFinal(value);

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

        return null;
    }

    /**
     * 进行Base64编码
     *
     * @param src 原字符串
     * @return 返回经过Base64编码后的字符串
     */
    public static String base64Encode(String src) throws Exception {
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(src.getBytes(DESEDE_CHARSET_NAME));
    }

    /**
     * 进行Base64编码
     *
     * @param buff 原字符串
     * @return 返回经过Base64编码后的字符串
     */
    public static String base64Encode(byte[] buff) throws Exception {
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(buff);
    }

    /**
     * 进行Base64解码
     *
     * @param src 经Base64编码后的字符串
     * @return 返回解码后的字符串
     * @throws Exception
     */
    public static String base64Decode(String src) throws Exception {
        Base64.Decoder decoder = Base64.getDecoder();
        return new String(decoder.decode(src), DESEDE_CHARSET_NAME);
    }

    /**
     * 进行Base64解码
     *
     * @param src 经Base64编码后的字符串
     * @return 返回解码后的字符串
     * @throws Exception
     */
    public static byte[] base64DecodeToBytes(String src) throws Exception {
        Base64.Decoder decoder = Base64.getDecoder();
        return decoder.decode(src);
    }


    public static String encryptString(String str) {
        try {
            byte[] encrypt = DESede.encrypt(DEFAULT_KEY.getBytes(), DEFAULT_DESEDE_IV.getBytes(), str.getBytes());
            String enStr = DESede.base64Encode(encrypt);
            return enStr;
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    /**
     * 字符串解密
     *
     * @throws Exception
     */
    public static String decryptString(String str) {
        //解密字符串
        try {
            byte[] strBytes = DESede.base64DecodeToBytes(str);
            return new String(DESede.decrypt(DEFAULT_KEY.getBytes(), DEFAULT_DESEDE_IV.getBytes(), strBytes));
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    public static void main(String[] args) throws Exception {
        /*System.out.println(encryptString("是的，孩子经常跟我们说听到奇怪的声音，甚至有时候能和声音对话起来。"));*/
    }
}
