package com.yxcheng.token.utils;

import javax.crypto.Cipher;
import javax.crypto.Mac;
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.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

public class Security {

	public static String charsetName = "UTF-8";

	public final static String toHex(byte[] md) {
		// 把密文转换成十六进制的字符串形式
		int j = md.length;
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'A', 'B', 'C', 'D', 'E', 'F' };
		char str[] = new char[j * 2];
		int k = 0;
		for (int i = 0; i < j; i++) {
			byte byte0 = md[i];
			str[k++] = hexDigits[byte0 >>> 4 & 0xf];
			str[k++] = hexDigits[byte0 & 0xf];
		}
		return new String(str);
	}

	private static int hexToNum(char c) {
		int num = 0;
		char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'A', 'B', 'C', 'D', 'E', 'F' };
		for (int j = 0; j < hexDigits.length; j++) {
			if (c == hexDigits[j])
				num = j;
		}
		return num;
	}

	public static byte[] toDecimal(String msg) {
		byte[] result = new byte[msg.length() / 2];
		char[] origional = msg.toCharArray();

		for (int i = 0; i < origional.length - 1; i++) {
			if (i % 2 == 0) {
				result[i / 2] = (byte) (hexToNum((origional[i])) * 16 + hexToNum(origional[i + 1]));
			}
		}
		return result;
	}

	/**
	 * MD5加密
	 * 
	 * @param s
	 * @return
	 */
	public final static String MD5(String s) {

		try {
			byte[] btInput = s.getBytes();
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			// 使用指定的字节更新摘要
			mdInst.update(btInput);
			// 获得密文
			byte[] md = mdInst.digest();

			return toHex(md);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * Description 根据键值进行加密
	 * 
	 * @param key
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws GeneralSecurityException
	 */
	public static String encrypt(String data, String key)
			throws GeneralSecurityException, UnsupportedEncodingException {
		byte[] src = data.getBytes(charsetName);
		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
		DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(charsetName));

		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		IvParameterSpec iv = new IvParameterSpec(key.getBytes(charsetName));
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
		return toHex(cipher.doFinal(src));
	}

	/**
	 * Description 根据键值进行解密
	 * 
	 * @param src
	 * @param key
	 *            加密键byte数组
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws Exception
	 */
	public static String decrypt(String src, String key)
			throws GeneralSecurityException, UnsupportedEncodingException {
		// 生成一个可信任的随机数源
		byte[] data = toDecimal(src);
		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

		DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(charsetName));

		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey securekey = keyFactory.generateSecret(desKeySpec);

		IvParameterSpec iv = new IvParameterSpec(key.getBytes(charsetName));

		cipher.init(Cipher.DECRYPT_MODE, securekey, iv);
		return new String(cipher.doFinal(data), charsetName);

	}

	/**
	 * 获得随机数字
	 * 
	 * @param num
	 *            位数
	 * @return
	 */
	public static String getRandom(int num) {
		Double key = Math.random() * 100000;
		String result = new Integer(key.intValue()).toString();
		if (result.length() > num) {
			result = result.substring(result.length() - num);
		} else {
			for (int i = num - result.length(); i > 0; i--) {
				result = "0" + result;
			}
		}
		return result;
	}

//	private static ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>();
//
//	public static String getCurrentString() {
//		if (null == dateFormat.get()) {
//			dateFormat.set(new SimpleDateFormat("yyyyMMddhhssmmSSS"));
//		}
//		return dateFormat.get().format(
//				new Timestamp(System.currentTimeMillis()));
//	}

	public static String getSignature(byte[] data, byte[] key)
			throws NoSuchAlgorithmException, InvalidKeyException {

		SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
		Mac mac = Mac.getInstance("HmacSHA1");
		mac.init(signingKey);
		byte[] rawHmac = mac.doFinal(data);
		String str = new String(rawHmac);
		return Md5.getEncode(rawHmac);

	}

	public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
		String data = "AccessKeyID=userid&SignatureNonce=123456&TimeStamp=2016-02-23T12:46:24Z&Version=1.0";
		String secretKey = "password";
		System.out.println(Security.getSignature(data.getBytes("utf-8"), secretKey.getBytes("utf-8")));
	}

	public static final String bytesToHexString(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();
	}


    public static String decodeTs(String cert,String token){
        String m1 = MD5Util.MD5Encode(MD5Util.MD5Encode(cert+token+cert)).replaceAll("a", "").replaceAll("b", "").replaceAll("c", "").replaceAll("d", "").replaceAll("e", "").replaceAll("f", "");
        String m2 = MD5Util.MD5Encode(MD5Util.MD5Encode(MD5Util.MD5Encode(token+cert+m1))).replaceAll("a", "").replaceAll("b", "").replaceAll("c", "").replaceAll("d", "").replaceAll("e", "").replaceAll("f", "");
        return m1+m2;
    }




}
