package cn.sh.stc.sict.cloud.common.core.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/** 字符串处理类 */
@SuppressWarnings("restriction")
public class CryptUtil {

    /**
	 * 将字节数据处理成base64字符串<br/>
	 * @param bts	字节数据
	 * @return	base64编码后的字符串(用于传输)
	 * @throws IOException
	 */
	public static String toBase64(byte[] bts) {
		if(bts==null || bts.length==0) {
			return null;
		}
		String base64Str = new BASE64Encoder().encode(bts);
		base64Str = base64Str.replace("\r", "").replace("\n", "");
		return base64Str;
	}

    /**
     * 将String处理成base64字符串<br/>
     * (用默认的String编码集)
     * @param oldStr	原字符串
     * @return base64编码后的字符串(用于传输)
     * @throws
     */
    public static String toBase64(String oldStr) {
    	if(oldStr == null) {
    		return null;
    	}
		byte[] bts = oldStr.getBytes(StandardCharsets.UTF_8);
		String base64Str = new BASE64Encoder().encode(bts);
		base64Str = base64Str.replace("\r", "").replace("\n", "");
		return base64Str;
	}

    /**
     * 将String处理成base64字符串<br/>
     * (用默认的String编码集)
     * @param oldStr	原字符串
     * @return base64编码后的字符串(用于传输)
     * @throws UnsupportedEncodingException
     */
    public static String toBase64(String oldStr, String charset) {
    	try {
	    	if(oldStr == null) {
	    		return null;
	    	}
	    	byte[] bts = oldStr.getBytes(charset);
			return new BASE64Encoder().encode(bts);
	    } catch (Exception e) {
			return null;
		}
    }


    /**
     * DES加密
     * @param text		要加密的数据
     * @param token		约定密串
     * @param charset	原文的编码集
     * @return	加密后的密文
     */
    public static String toDES(String text, String token, String charset) {
    	try {
    		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    		byte[] btToken = charset==null?token.getBytes():token.getBytes(charset);
    		byte[] btText = charset==null?text.getBytes():text.getBytes(charset);
    		DESKeySpec desKeySpec = new DESKeySpec(btToken);
    		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
    		IvParameterSpec iv = new IvParameterSpec(btToken);
    		cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
    		byte[] bts = cipher.doFinal(btText);
    		return toBase64(bts);
    	} catch (Exception e) {
    		return null;
		}
    }


    /**
     * AES加密
     * @param text		要加密的数据
     * @param token		约定密串
     * @param charset	原数据字符集
     * @return	加密后的密文
     */
    public static String toAESForSplit(String text, String token, String charset) {
    	try {
//    		KeyGenerator kgen = KeyGenerator.getInstance("AES");
//    		kgen.init(128, new SecureRandom(charset==null?token.getBytes():token.getBytes(charset)));
//    		SecretKey secretKey = kgen.generateKey();
//    		byte[] enCodeFormat = secretKey.getEncoded();
//    		SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//    		Cipher cipher = Cipher.getInstance("AES");// 创建密码器
//    		byte[] btText = charset==null?text.getBytes():text.getBytes(charset);
//    		cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
//    		byte[] bts = cipher.doFinal(btText);
    		byte[] data = charset==null?text.getBytes():text.getBytes(charset);
    		int maxDataSize = 127;
    		String result = "";
    		char chs[] = text.toCharArray();

    		int size = 0;
    		int lastIndex = 0;
    		for(int i=0; i<text.length(); i++) {
    			int length = charset==null?String.valueOf(chs[i]).getBytes().length:String.valueOf(chs[i]).getBytes(charset).length;
				if(size+length > maxDataSize) {
					i--;
				} else if(i == text.length()-1) {
					size += length;
				} else {
					size += length;
					continue;
				}
				byte[] onceBts = Arrays.copyOfRange(data, lastIndex, lastIndex+size);
				KeyGenerator kgen = KeyGenerator.getInstance("AES");
				kgen.init(128);
				Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
				cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(token.getBytes(), "AES"));
				byte[] tempBts = cipher.doFinal(onceBts);
				result += toBase64(tempBts) + "_";
				lastIndex += size;
				size = 0;
    		}
    		return result.trim().replace("\r", "").replace("\n", "");
    	} catch (Exception e) {
        	return null;
        }
    }

    /**
     * AES加密
     * @param text		要加密的数据
     * @param token		约定密串
     * @param charset	原数据字符集
     * @return	加密后的密文
     */
    public static String toAES(String text, String token, String charset) {
    	try {
//    		KeyGenerator kgen = KeyGenerator.getInstance("AES");
//    		kgen.init(128, new SecureRandom(charset==null?token.getBytes():token.getBytes(charset)));
//    		SecretKey secretKey = kgen.generateKey();
//    		byte[] enCodeFormat = secretKey.getEncoded();
//    		SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//    		Cipher cipher = Cipher.getInstance("AES");// 创建密码器
//    		byte[] btText = charset==null?text.getBytes():text.getBytes(charset);
//    		cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
//    		byte[] bts = cipher.doFinal(btText);

			KeyGenerator kgen = KeyGenerator.getInstance("AES");
			kgen.init(128);
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(token.getBytes(), "AES"));
			byte[] tempBts = cipher.doFinal(charset==null?text.getBytes():text.getBytes(charset));
    		return toBase64(tempBts).replace("\r", "").replace("\n", "");
    	} catch (Exception e) {
        	return null;
        }
    }

    /**
     * AES加密
     * @param text		要加密的数据
     * @param token		约定密串
     * @return	加密后的密文
     */
    public static String toAESForSplit(String text, String token) {
    	return toAESForSplit(text, token, null);
    }

    /**
	 * 将base64字符串处理成String字节<br/>
	 * @param str	base64的字符串
	 * @return	原字节数据
	 * @throws IOException
	 */
	public static byte[] base64ToByte(String str) {
		try {
			if(str == null) {
				return null;
			}
			return new BASE64Decoder().decodeBuffer(str);
		} catch (Exception e) {
			return null;
		}
	}
    /**
     * AES加密
     * @param text		要加密的数据
     * @param token		约定密串
     * @return	加密后的密文
     */
    public static String toAES(String text, String token) {
    	return toAES(text, token, null);
    }

    /** AES解密
     * @param text		要加密的数据
     * @param token		约定密串
     * @param charset	原数据字符集
     * @return	解密后的原文
     */
    public static String AESToString(String text, String token, String charset) {
    	try {
    		KeyGenerator kgen = KeyGenerator.getInstance("AES");
    		kgen.init(128);
    		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(token.getBytes(), "AES"));
            byte[] bts = cipher.doFinal(base64ToByte(text));
            return charset==null?new String(bts):new String(bts, charset);
		} catch (Exception e) {
        	return null;
		}
    }

    /** AES解密
     * @param text		要加密的数据
     * @param token		约定密串
     * @param charset	原数据字符集
     * @return	解密后的原文
     */
    public static String AESToStringForSplit(String text, String token, String charset) {
    	try {
//        	byte[] btText = base64ToByte(text);
//        	KeyGenerator kgen = KeyGenerator.getInstance("AES");
//        	kgen.init(128, new SecureRandom(charset==null?token.getBytes():token.getBytes(charset)));
//        	SecretKey secretKey = kgen.generateKey();
//        	byte[] enCodeFormat = secretKey.getEncoded();
//        	SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//        	Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
//        	cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
//        	byte[] bts = cipher.doFinal(btText);
    		text = text.replace("\r", "").replace("\n", "");
    		String[] datas = text.split("_");
    		String result = "";
    		for(String data : datas) {
    			KeyGenerator kgen = KeyGenerator.getInstance("AES");
        		kgen.init(128);
        		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(token.getBytes(), "AES"));
                byte[] bts = cipher.doFinal(base64ToByte(data));
                result += charset==null?new String(bts):new String(bts, charset);
    		}
    		return result;
        } catch (Exception e) {
        	return null;
        }
    }

    /** AES解密
     * @param text		要加密的数据
     * @param token		约定密串
     * @return	解密后的原文
     */
    public static String AESToStringForSplit(String text, String token) {
    	return AESToStringForSplit(text, token, null);
    }

    /** AES解密
     * @param text		要加密的数据
     * @param token		约定密串
     * @return	解密后的原文
     */
    public static String AESToString(String text, String token) {
    	return AESToString(text, token, null);
    }


    public static void main(String[] args) {
    	String token = "1qaz@WSX3edc$RFV";
    	String name = "admin";
    	String pwd = "123456";
    	String pwdjm = toAES(pwd, token);
		System.out.println(toAES(name, token));
    	System.out.println(pwdjm);

//    	String pwdorigin = AESToString(pwdjm, token);
//    	System.out.println(pwdorigin);
	}


//	// client-id secret-key 加密
//	public static void main(String[] args) {
//		System.setProperty("jasypt.encryptor.password", "sict");
//		StringEncryptor stringEncryptor = new DefaultLazyEncryptor(new StandardEnvironment());
//
//		//加密方法
//		System.out.println(stringEncryptor.encrypt("sict"));
//		System.out.println(stringEncryptor.encrypt("sict_pwd"));
//		//解密方法
//		// System.out.println(stringEncryptor.decrypt("4K2Bgkak5riMyBgakm0i4A=="));
//		// System.out.println(stringEncryptor.decrypt("S295/gaPlyjyQwlC0w0Rbs0Wid5Wck9F"));
//	}
}
