package com.yihu.jw.utils.encode;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.jw.utils.JSONUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;

public class AESUtils {
    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    public AESUtils() {
    }

    public static byte[] initSecretKey() throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance("AES");
        kg.init(128);
        SecretKey secretKey = kg.generateKey();
        return secretKey.getEncoded();
    }

    public static String generatorSecretKey() throws Exception {
        return DigestUtils.md5Hex(initSecretKey()).substring(8, 24);
    }

    public static Key toKey(byte[] key) {
        return new SecretKeySpec(key, "AES");
    }

    public static String encrypt(String data, String key) throws Exception {
        return Base64.encodeBase64String(encrypt(data.getBytes("utf-8"), toKey(key.getBytes("utf-8")), "AES/ECB/PKCS5Padding"));
    }

    public static String decrypt(String data, String key) throws Exception {
        return new String(decrypt(Base64.decodeBase64(data.getBytes("utf-8")), toKey(key.getBytes("utf-8")), "AES/ECB/PKCS5Padding"),"utf-8");
    }

    public static byte[] encrypt(byte[] data, Key key) throws Exception {
        return encrypt(data, key, "AES/ECB/PKCS5Padding");
    }

    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        return encrypt(data, toKey(key), "AES/ECB/PKCS5Padding");
    }

    public static byte[] encrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);
        cipher.init(1, key);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        return decrypt(data, key, "AES/ECB/PKCS5Padding");
    }

    public static byte[] decrypt(byte[] data, Key key) throws Exception {
        return decrypt(data, key, "AES/ECB/PKCS5Padding");
    }

    public static byte[] decrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {
        Key k = toKey(key);
        return decrypt(data, k, cipherAlgorithm);
    }

    public static byte[] decrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);
        cipher.init(2, key);
        return cipher.doFinal(data);
    }

    private static String showByteArray(byte[] data) {
        if(null == data) {
            return null;
        } else {
            StringBuilder sb = new StringBuilder("{");
            byte[] arr$ = data;
            int len$ = data.length;

            for(int i$ = 0; i$ < len$; ++i$) {
                byte b = arr$[i$];
                sb.append(b).append(",");
            }

            sb.deleteCharAt(sb.length() - 1);
            sb.append("}");
            return sb.toString();
        }
    }

    public static void main(String[] args) throws Exception {
        String key = generatorSecretKey();
        System.out.println("key: " + key);
        String[] original = new String[]{"hello  world!"};

        try {
            String encrypt = encrypt((new ObjectMapper()).writeValueAsString(original), key);
            System.out.println("encrypt: " + encrypt);
            String decrypt = decrypt(encrypt, key);
            System.out.println("decrypt: " + decrypt);
            System.out.println("original: " + JSONUtils.parse(decrypt.getBytes(), String[].class));
        } catch (Exception var5) {
            throw new IllegalStateException(var5);
        }
    }
}
