package com.szxgl.nft.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.UnixCrypt;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.sql.PreparedStatement;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Utility implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * cookie默认保存时长 （1天）
	 */
	private static final int COOKIE_DEFAULT_MAXAGE = 3600 * 24 * 1;

	protected static Utility instance = null;

	/**
	 * 用户密码正则表达式  (必须由数字和字母组成, 长度为6-18位)
	 * ^ 匹配一行的开头位置
	 * (?![0-9]+$) 预测该位置后面不全是数字
	 * (?![a-zA-Z]+$) 预测该位置后面不全是字母
	 * [0-9A-Za-z]{6,18} 由6-18位数字或者字母组成
	 * $ 匹配行结尾位置
	 */
	public static String REGEX_USERPWD = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$";

	public static synchronized void setInstance(boolean clear) {
		if (clear)
			instance = null;
		else if (instance == null)
			instance = new Utility();
	}

	public static Utility getUtilityInstance() {
		if (instance == null)
			setInstance(false);
		return instance;
	}

	protected Utility() {
		instance = null;
	}


	/**
	 * Convert integer string array into integer array
	 * @param array
	 * @return
	 * @throws Exception
	 */
	public static int[] toIntArray(String[] array) {
		int[] result = new int[array.length];
		int count = 0;
		for (int i = 0; i < array.length; i++) {
			if (array[i] != null && !array[i].trim().equals("") && !array[i].trim().equals("undefined"))
				result[count++] = Integer.parseInt(array[i]);
		}
		return result;
	}

	/**
	 * Convert integer arraylist into integer array
	 * @param array
	 * @return
	 * @throws Exception
	 */
	public static int[] toIntArray(ArrayList<String> array) throws Exception {
		int[] result = new int[array.size()];
		int count = 0;
		for (int i = 0; i < array.size(); i++) {
			String item = array.get(i);
			if (item != null && !item.trim().equals(""))
				result[count++] = Integer.parseInt(item);
		}
		return result;
	}

	public static int[] toIntArray(String str){
		if(str == null || str.equals("")) return null;
		int[] result;
		if(str.indexOf(",")!=-1){
			String[] strArr = str.split(",");
			result =toIntArray(strArr);
		}else{
			result = new int[]{Integer.parseInt(str)};
		}

		return result;
	}

	public static long[] toLongArray(String str){
		if(str == null || str.equals("")) return null;
		long[] result;
		if(str.indexOf(",")!=-1){
			String[] strArr = str.split(",");
			result =toLongArray(strArr);
		}else{
			result = new long[]{Long.parseLong(str)};
		}
		return result;
	}

	public static long[] toLongArray(String[] array) {
		long[] result = new long[array.length];
		int count = 0;
		for (int i = 0; i < array.length; i++) {
			if (array[i] != null && !array[i].trim().equals("") && !array[i].trim().equals("undefined"))
				result[count++] = Long.parseLong(array[i]);
		}
		return result;
	}

	/**
	 * This function will convert the string to a unicode string. (e.g. "\u7f51")
	 *
	 * @param value
	 * @return
	 */
	public static String encodeDec(String value) throws Exception {
		// Set the contant type as "UTF8".
		// <META http-equiv=content-tyhpe content="text/html; charset=UTF-8">
		if (value == null || value.equals(""))
			return value;

		String buffer = value;
		//buffer = new String(buffer.getBytes("ISO8859_1"), "UTF8");
		buffer = URLEncoder.encode(buffer, "Unicode");

		// Sometime the language in reverse encodeing
		boolean reverse = false;
		if (buffer.startsWith("%FE%FF"))
			reverse = true;

		StringBuffer sb = new StringBuffer();
		String[] sc = buffer.split(!reverse ? "%FF%FE" : "%FE%FF");
		// for each of unicode set
		for (int i = 0; i < sc.length; i++) {
			String si = sc[i];
			// for each of char in unicode line
			for (int j = 0; j < si.length(); j++) {
				char ch = si.charAt(j);
				if (ch == '%') {
					sb.append("&#");
					if (!reverse) {
						sb.append(Integer.parseInt(si.substring(j + 4, j + 6).toLowerCase()
								+ si.substring(j + 1, j + 3).toLowerCase(), 16));
					} else {
						sb.append(Integer.parseInt(si.substring(j + 1, j + 3).toLowerCase()
								+ si.substring(j + 4, j + 6).toLowerCase(), 16));
					}
					sb.append(";");
					j += 5;
				} else {
					String ss = si.substring(j, j + 1);
					if (ss.equals("+"))
						ss = " ";
					sb.append(ss);
				}
			}
		}
		return sb.toString();
	}

	public static String decodeDec(String value) throws Exception {
		// Back to unicode from string contains unicode string (i.e. \u4e09)
		boolean fffe = false;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < value.length(); i++) {
			if (value.charAt(i) == '&' && value.charAt(i + 1) == '#') {
				if (!fffe) {
					sb.append("%FF%FE");
					fffe = true;
				}
				int nexti = value.indexOf(';', i + 2);
				String code = value.substring(i + 2, nexti);
				String hex = "0000" + Integer.toHexString(Integer.parseInt(code));
				hex = hex.substring(hex.length() - 4);
				sb.append("%" + hex.substring(2, 4));
				sb.append("%" + hex.substring(0, 2));
				i = nexti;
			} else {
				fffe = false;
				if (value.charAt(i) == ' ')
					sb.append('+');
				else
					sb.append(value.charAt(i));
			}
		}
		return URLDecoder.decode(sb.toString(), "Unicode");
	}

	public static String decodeISO(String value) throws Exception {
		if (value == null)
			return "";
		return new String(value.getBytes("ISO8859_1"), "UTF8");
	}

	public static String decodeISO(String value, String sourceCharSet) throws Exception {
		if (value == null)
			return "";
		if (sourceCharSet == null) return value;
		if (sourceCharSet.trim().equals("")) return value;
		return new String(value.getBytes(sourceCharSet), "UTF8");
	}

	public static String encodeHTML(String value) {
		if (value == null)
			return "";
		value = value.replaceAll("\"", "&#34;").replaceAll("'", "&#39;");
		value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
		return value;
	}

	public static String decodeHTML(String value) {
		if (value == null)
			return "";
		value = value.replaceAll("&#34;", "\"").replaceAll("&#39;", "'");
		value = value.replaceAll("&lt;", "<").replaceAll("&gt;", ">");
		return value;
	}

	/**
	 * This function will convert the string to a unicode string. (e.g. "\u7f51")
	 *
	 * @param value
	 * @return
	 */
	public static String toUnicodeString(String value) throws Exception {
		// Set the contant type as "UTF8".
		// <META http-equiv=content-tyhpe content="text/html; charset=UTF-8">
		if (value == null || value.equals(""))
			return value;

		String buffer = value;
		buffer = new String(buffer.getBytes("ISO8859_1"), "UTF8");
		buffer = URLEncoder.encode(buffer, "Unicode");

		StringBuffer sb = new StringBuffer();
		String[] sc = buffer.split("%FF%FE");
		// for each of unicode set
		for (int i = 0; i < sc.length; i++) {
			String si = sc[i];
			// for each of char in unicode line
			for (int j = 0; j < si.length(); j++) {
				char ch = si.charAt(j);
				if (ch == '%') {
					sb.append('\\').append('u');
					sb.append(si.substring(j + 4, j + 6).toLowerCase());
					sb.append(si.substring(j + 1, j + 3).toLowerCase());
					j += 5;
				} else {
					String ss = si.substring(j, j + 1);
					if (ss.equals("+"))
						ss = " ";
					sb.append(ss);
				}
			}
		}
		return sb.toString();
	}

	/**
	 * Create a instance from a class
	 *
	 * @param service
	 * @return @throws
	 *         ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static Object instantiate(String service) throws ClassNotFoundException, InstantiationException,
			IllegalAccessException {
		ClassLoader classloader = Thread.currentThread().getContextClassLoader();
		Class<?> instance = classloader.loadClass(service);
		return instance.newInstance();
	}

	public static double getRoundUp(double d, int scale) {
		double result = d;
		BigDecimal bd = new BigDecimal(d);
		result = bd.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
		return result;
	}

	public static float getRoundUp(float d, int scale) {
		float result = d;
		BigDecimal bd = new BigDecimal(d);
		result = bd.setScale(scale, BigDecimal.ROUND_HALF_UP).floatValue();
		return result;
	}

	public static Calendar getCalendar(Date date) throws Exception {
		Calendar result = Calendar.getInstance();
		result.setTime(date);
		return result;
	}

	public static Calendar getCalendar(long milliseconds) throws Exception {
		Calendar result = Calendar.getInstance();
		result.setTimeInMillis(milliseconds);
		return result;
	}

	public static String getTimeStampWithMillis() {
		return getTimeStampWithMillis(Calendar.getInstance());
	}

	public static String getTimeStampWithMillis(Calendar calendar) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String result = sdf.format(calendar.getTime());
		return result;
	}

	/**
	 * Convert a string with format "yyyyMMddHHmmss" into Calendar object
	 * @param date
	 * @return
	 * @throws Exception
	 */
	public static Calendar getCalendar(String date) throws Exception {
		if (date == null || date.trim().equals(""))
			return null;

		for (int i = date.length(); i < 14; i++)
			date += "0";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		Calendar result = Calendar.getInstance();

		try {
			result.setTime(sdf.parse(date));
		} catch (ParseException e) {
			result = null;
		}
		return result;
	}

	public static Calendar getCalendar(String date, String format) throws Exception {
		if (date == null || date.trim().equals(""))
			return null;

		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Calendar result = Calendar.getInstance();

		try {
			result.setTime(sdf.parse(date));
		} catch (ParseException e) {
			result = null;
		}
		return result;
	}

	public static String getDateString(Calendar date) throws Exception {
		if (date == null)	return "";

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		return sdf.format(date.getTime());
	}

	public static String getDateString(Calendar date, String format){
		if (date == null)	return "";
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date.getTime());
	}
	// 12 to 24
	public static String TimeFormat(String time){
		if(time==null || time.trim().equals("")) return null;

		if(time.indexOf("PM")!=-1 || time.indexOf("pm")!=-1){
			String[] strarr = time.split(":");
			int HH=Integer.parseInt(strarr[0]);
			if(HH==1){
				HH=13;
			}else if(HH==2){
				HH=14;
			}else if(HH==3){
				HH=15;
			}else if(HH==4){
				HH=16;
			}else if(HH==5){
				HH=17;
			}else if(HH==6){
				HH=18;
			}else if(HH==7){
				HH=19;
			}else if(HH==8){
				HH=20;
			}else if(HH==9){
				HH=21;
			}else if(HH==10){
				HH=22;
			}else if(HH==11){
				HH=23;
			}else if(HH==12){
				HH=00;
			}
			time = HH+":"+strarr[1];

		}
		return time;
	}

	public static String getHttpContent(String urlStr, String encoding) throws Exception {
		URL url = new URL(urlStr);
		InputStream is = null;
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		try {
			if (connection.getResponseCode() != 200) {
				//return "Error: " + connection.getResponseCode() + " " + connection.getResponseMessage();
				is = connection.getErrorStream();
			} else {
				is = connection.getInputStream();
			}

			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			byte[] buffer = new byte[16384];
			int count;
			while ((count = is.read(buffer)) != -1) {
				bos.write(buffer, 0, count);
			}
			return bos.toString(encoding);
		} finally {
			connection.disconnect();
		}
	}

	public static byte[] objectToByteArray(Object obj) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		oos.writeObject(obj);
		oos.flush();
		oos.close();
		return bos.toByteArray();
	}

	public static byte[] InputStreamToByteArray(InputStream is) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		byte[] buffer = new byte[16384];
		int count;
		while ((count = is.read(buffer)) != -1) {
			bos.write(buffer, 0, count);
		}
		return bos.toByteArray();
	}


	public static Object byteArrayToObject(byte[] array) throws Exception {
		ByteArrayInputStream bis = new ByteArrayInputStream(array);
		ObjectInputStream ois = new ObjectInputStream(bis);
		return ois.readObject();
	}

	public static void byteArrayToFile(byte[] content, String filename) throws Exception {
		FileOutputStream out = new FileOutputStream(filename);
		out.write(content);
		out.flush();
		out.close();
	}

	public static byte[] fileToByteArray(String filename) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		FileInputStream fos = new FileInputStream(filename);
		byte[] buffer = new byte[10240];
		int count;
		while ((count = fos.read(buffer)) != -1)
			bos.write(buffer, 0, count);
		fos.close();
		return bos.toByteArray();
	}

	public URL getWebInfURL() throws Exception {
		URL url = getClass().getResource("");
		if (url != null) {
			return new URL(url.getProtocol(), url.getHost(), url.getFile().substring(0,
					url.getFile().indexOf("WEB-INF/classes"))
					+ "WEB-INF");
		} else {
			String classesPath = getClass().getClassLoader().getResource("").toString();
			String location = classesPath.substring(0, classesPath.indexOf("/classes"));
			return new URL(location);
		}
	}

	public static String getRegExpContent(String content, String pattern, int index) throws Exception {
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(content);
		if (m.find()) {
			return m.group(index);
		}
		return "";
	}

	public static int[] getIntegerArray(String values) throws Exception {
		String[] slice = values.split(",");
		int[] result = new int[slice.length];
		for (int i = 0; i < slice.length; i++)
			result[i] = Integer.parseInt(slice[i]);
		return result;
	}

	/**
	 * Return the file name without extension
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static String getFileName(String filename) throws Exception {
		int i = filename.lastIndexOf('.');
		if (i == -1)
			return filename;
		return filename.substring(0, i);
	}

	/**
	 * Return the file extension only
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static String getFileExtension(String filename) throws Exception {
		int i = filename.lastIndexOf('.');
		if (i == -1)
			return "";
		return filename.substring(i + 1);
	}

	public static String getRandomFileName() throws Exception {
		Random rand = new Random((Calendar.getInstance()).getTimeInMillis());
		return "_" + Math.abs(rand.nextInt()) + ".tmp";
	}

	public static String encodeCDATA(String str) {
		return str.replaceAll("<", "A1X78D2L").replaceAll(">", "B8N62K09").replaceAll("&", "C19PWK8B").replaceAll("\"","7HU3G1Z6");
	}

	public static String decodeCDATA(String str) {
		return str.replaceAll("A1X78D2L", "<").replaceAll("B8N62K09", ">").replaceAll("C19PWK8B", "&").replaceAll("7HU3G1Z6", "\"");
	}

	public static String getQuotedString(String str) {
		return str.replaceAll("\"", "\\\\\"");
	}
	/*
	public static String getValidPassword(String password) {
		if (password == null) return Constant.pwdSuffix;
		else if (password.trim().length() < 4) return password.trim() + Constant.pwdSuffix;
		else return password.trim();
	}
*/
	public static String getFormatedDate(Calendar date) {
		return getFormatedDate(date, "yyyy-MM-dd HH:mm:ss");
	}

	public static String getFormatedDate(Date date) {
		if(date==null)return null;
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return getFormatedDate(c);
	}

	public static String getFormatedDate(Calendar date, String format) {
		if (date == null)
			return "";
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date.getTime());
	}

	public static String getFormatedTimeStamp() {
		return getFormatedTimeStamp(Calendar.getInstance());
	}

	public static String getFormatedTimeStamp(Calendar calendar) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		return sdf.format(calendar.getTime());
	}

	public static String getTimeStamp() {
		Calendar calendar = Calendar.getInstance();
		return getTimeStamp(calendar);
	}

	public static String getTimeStamp(Calendar calendar) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		String result = sdf.format(calendar.getTime());
		result = result + "000";
		return result;
	}


	public static String getFormatedFileSize(long value) {
		double kb = value / 1024.00;
		DecimalFormat df = new DecimalFormat("#0.00");
		return df.format(kb);
	}

	public static String getFormatedDecimal(double value) {
		return getFormatedDecimal(value, "#0.00");
	}

	public static String getFormatedDecimal(double value, int decimal) {
		String format = "#0.";
		if (decimal == 0) format = "#0";
		else {
			for (int i = 1; i <= decimal; i++) format += "0";
		}
		return getFormatedDecimal(value, format);
	}

	public static String getFormatedDecimal(double value, String format) {
		DecimalFormat df = new DecimalFormat(format);
		return df.format(value);
	}

	public static Date getMonthLastDay(int year, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month, 1);
		calendar.add(Calendar.DATE, -1);
		return calendar.getTime();
	}

	public static String getDateFormat(Date date, String format) {
		if (date == null) return "";
		SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.US);
		return dateFormat.format(date);
	}

	public static java.sql.Date UtilDateToSQLDate(Date utilDate) {
		if (utilDate == null) return null;
		return new java.sql.Date(utilDate.getTime());
	}

	public static java.sql.Timestamp UtilDateToSQLTimeStamp(Date utilDate) {
		if (utilDate == null) return null;
		return new java.sql.Timestamp(utilDate.getTime());
	}

	public static Date SQLDateToUtilDate(java.sql.Date SQLDate) {
		if (SQLDate == null) return null;
		return new Date(SQLDate.getTime());
	}

	public static Date SQLDateToUtilDate(java.sql.Timestamp SQLDate) {
		if (SQLDate == null) return null;
		return new Date(SQLDate.getTime());
	}

	public static Date parseDate(String strDate, String pattern) throws Exception {
		if (strDate == null || strDate.trim().equals("")) return null;
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		Date date = format.parse(strDate);
		return date;
	}

	public static String getSearchFormat(String pattern) {
		if (pattern == null) return "%";
		pattern = pattern.trim();	// format maybe : A, A%, %A%, A%B%, %A"B
		if (pattern.equals("")) {
			pattern = "%";
		} else if (pattern.indexOf("%") == -1) {
			pattern = "%" + pattern + "%";
		}
		return pattern;
	}

	public static String getLeadingZero(int intValue, int maxLength) {
		String result = String.valueOf(intValue);
		if (result.length() < maxLength) {
			while (result.length() < maxLength) {
				result = "0" + result;
			}
		}
		return result;
	}

	public static String getQuantityAsString(float qty) {
		DecimalFormat df = new DecimalFormat("#0.00");
		return df.format(qty);
	}

	public static String getQuantityAsString(double qty) {
		DecimalFormat df = new DecimalFormat("#0.00");
		return df.format(qty);
	}

	public static String getQuantityAsString(float amt, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(amt);
	}

	public static String getQuantityAsString(double amt, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(amt);
	}

	public static String getInvoiceAsString(float amt) {
		DecimalFormat df = new DecimalFormat("#,##0.00");
		return df.format(amt);
	}

	public static String getAmountAsString(float amt, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(amt);
	}

	public static String getAmountAsString(double amt, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(amt);
	}

	public static String getFloatFormat(float f, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(f);
	}

	public static String getDoubleFormat(double d, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(d);
	}

	public static Date parseExcelDate(String Date) {
		Calendar calendar = Calendar.getInstance();
		long millis = (long) (Integer.parseInt(Date) - 25569)*24*60*60*1000;
		calendar.setTimeInMillis(millis);
		return calendar.getTime();
	}

    public static double mul(double d1, double d2) {
    	BigDecimal b1 = new BigDecimal(String.valueOf(d1));
    	BigDecimal b2 = new BigDecimal(String.valueOf(d2));

    	return b1.multiply(b2).doubleValue();
    }

    public static double mul(BigDecimal b1, double d2) {
    	BigDecimal b2 = new BigDecimal(String.valueOf(d2));

    	return b1.multiply(b2).doubleValue();
    }

    public static double round(double d, int scale) {
    	if(scale<0){
    		throw new IllegalArgumentException("The scale must be a positive integer or zero");
    	}
   		BigDecimal b = new BigDecimal(String.valueOf(d));
   		BigDecimal one = new BigDecimal("1");

    	return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

	public static String getIDAsString(ArrayList<?> idList, int idFrom, int idTo) {
		String IDs = null;
		if (idList != null && idList.size() > 0) {
			if (idFrom < 0) idFrom = 0;
			if (idTo > idList.size()) idTo = idList.size();
			int lp;
			IDs = idList.get(idFrom).toString();
			if (idList.size() > 1 && idTo > idFrom) {
				for (lp = idFrom+1; lp < idTo; lp ++) IDs += "," + idList.get(lp).toString();
			}
		}
		return IDs;
	}

	public static String getPreparedParameterList(int fromID, int toID) {
		String result = "";
		for (int i = fromID; i <= toID; i++) {
			if (i == fromID) result += "?";
			else result += ",?";
		}
		return result;
	}

	public static void setPreparedParameterList(PreparedStatement stmt, int startParamIndex, ArrayList<Integer> idList, int fromID, int toID) throws Exception {
		int idx = startParamIndex;
		for (int i = fromID; i <= toID; i++) {
			stmt.setInt(idx, idList.get(i).intValue());
			idx ++;
		}
	}

	public static String replaceMailAddress(String mailAddress, String oldPattern, String newPattern) {
		if (mailAddress == null || mailAddress.trim().equals("") || oldPattern == null || newPattern == null)
			return mailAddress;
		else {
			return mailAddress.trim().replaceAll(oldPattern, newPattern);
		}
	}

	public static String getValidMailAddress(String mailAddress, String defaultAddress) {
		if (mailAddress != null && !mailAddress.trim().equals(""))
			return mailAddress;
		else
			return defaultAddress;
	}

	public static String getValidString(String str) {
		if (str == null) return "";
		else return str;
	}

	public static String[] getMailTo(String to) {
		String[] toAC = null;
		if (to != null && to.indexOf("@") != -1) {
			if (to.indexOf(",") != -1) toAC = to.split(",");
			else if (to.indexOf(";") != -1) toAC = to.split(";");
			else if (to.indexOf(" ") != -1) toAC = to.split(" ");
			else {
				toAC = new String[1];
				toAC[0] = to;
			}
		}
		return toAC;
	}

	public static int getASCII(String str) {
		int result = 48;
		if (str != null && !str.trim().equals("")) {
			result = 48 + Integer.parseInt(str);
		}
		return result;
	}

	public static void getKeyAsVector(String s_key, Vector<String> v_key) {
		int idx;
		if (s_key != null && !s_key.trim().equals("")) {
			if (s_key.startsWith(".")) s_key = s_key.substring(1);
			while (s_key.length() > 0) {
				idx = s_key.indexOf(".");
				if (idx != -1) {
					v_key.addElement(s_key.substring(0, idx));
					s_key = s_key.substring(idx+1);
				} else {
					v_key.addElement(s_key);
					s_key = "";
				}
			}
		}
	}

	public static String getNameFromAscII(String s_key, int startIndex, int length) {
		Vector<String> v_key = new Vector<String>();
		Utility.getKeyAsVector(s_key, v_key);
		String result = getNameFromAscII(v_key, startIndex, length);
		v_key = null;
		return result;
	}

	public static String getNameFromAscII(Vector<String> v_key, int startIndex, int length) {
		String result = "";
		if (length > v_key.size() - startIndex) length = v_key.size() - startIndex;
		for (int i = startIndex; i < startIndex + length; i++) {
			result += (char)Integer.parseInt(v_key.elementAt(i));
		}
		return result;
	}

	public static String NameToASCII(String str) {
		String result = null;
		char[] ch = str.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			if (result == null) result = String.valueOf((int)ch[i]);
			else result = result + "." + String.valueOf((int)ch[i]);
		}
		return result;
	}

    public static void writeLog(String log) {
		try {
			System.out.println(getFormatedTimeStamp() + " : " + log);
		} catch (Exception e) {
		}
	}

	public static String getLoggerCommandShellPath() throws Exception {
		String LoggerCommandShellPath = "classes";

		URL webInf = Utility.getUtilityInstance().getWebInfURL();
		URL url = new URL(webInf.getProtocol(), webInf.getHost(), webInf.getFile() + "/" + LoggerCommandShellPath);
		LoggerCommandShellPath = url.getHost() + url.getFile();

		File file = new File(LoggerCommandShellPath);
		if (!file.exists())	file.mkdirs();
		return file.getCanonicalPath();
	}

	public static String intToHex(int i) {
		String result = Integer.toHexString(i).trim();
		if (result.length() == 0) result = "00";
		if (result.length() == 1) result = "0" + result;
		return result;
	}

	public static int HexToInt(String s) {
		return Integer.parseInt(Integer.valueOf(s, 16).toString());
	}

	public static ArrayList<String> str2List(String str){
		ArrayList<String> list = new ArrayList<>();
		if(str!=null && str.trim().length()>0){
			if(str.indexOf(",")!=-1){
				String[] arr = str.split(",");
				for (String string : arr) {
					list.add(string);
				}
			}else{
				list.add(str);
			}
		}
		return list;
	}

    public static String getUUID(){
    	return UUID.randomUUID().toString();
    }

    public static String getFileSuffix(String filename){
    	String suffix="";
    	if(filename!=null && filename.indexOf(".")!=-1)suffix=filename.substring(filename.lastIndexOf("."));
    	return suffix;
	}

    public static String getFileSuffix(File file){
    	String fileName=file.getName();
    	return getFileSuffix(fileName);
    }
    /*
    public static String getPorjectPath(){
    	String nowpath = System.getProperty("user.dir");
    	nowpath=nowpath.replace("bin", "webapps");  //把bin 文件夹变到 webapps文件里面
    	nowpath+=File.separator+Constant.ProjectName;  //拼成D:\java\software\apache-tomcat-6.0.14\webapps\sz_pro
    	return nowpath;
    }
    */
    public static String getClientIPAddr(HttpServletRequest request) {
    	String ip = request.getHeader("x-forwarded-for");
    	if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个IP值，第一个为真实IP。
            int index = ip.indexOf(',');
            if (index != -1) {
            	ip = ip.substring(0, index);
            }
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("PRoxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        	ip = request.getHeader("X-Real-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

	 public static String trimExtension(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int i = filename.lastIndexOf('.');
            if ((i >-1) && (i < (filename.length()))) {
                return filename.substring(0, i);
            }
        }
        return filename;
    }

	public static String listToString(List<?> stringList){
		if (stringList==null) {
            return null;
        }
        StringBuilder result=new StringBuilder();
        boolean flag=false;
        for (Object string : stringList) {
            if (flag) {
                result.append(",");
            }else {
                flag=true;
            }
            result.append(String.valueOf(string));
        }
        return result.toString();
	}

	public static boolean strIsEqual(String str1, String str2){
		if(str1 == null)str1="";
		if(str2 == null)str2="";
		if(str1.equals(str2) || str1.trim().equals(str2.trim()))return true;
		else return false;
	}

	/**
	 * 判断是否是整数
	 * @param str
	 * @return
	 */
	public static boolean isNumber(String str){
		if(StringUtils.isEmpty(str))return false;
		try {
			Long.parseLong(str);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 判断是否是浮点数
	 * @param str
	 * @return
	 */
	public static boolean isDouble(String str){
		if(StringUtils.isEmpty(str))return false;
		try {
			Double.parseDouble(str);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 密码加密方法
	 * @param pwd
	 * @return
	 */
	public static String encryptPwd(String pwd){
		if(StringUtils.isEmpty(pwd))return null;
		else return UnixCrypt.crypt(pwd, DigestUtils.sha256Hex(pwd));
	}

	/**
	 * 优惠码的生成, 默认6为长度
	 * @return
	 */
	public static String getCode() {
		return getCode(6);
	}

	public static String getCode(int length) {
		char[] chs = { 'a', 'b', 'c', '1', '2', '3', '4', '5', 'd', 'e', 'f',
				'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
				's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '6', '7', '8', '9' };
		SecureRandom random = new SecureRandom();
		final char[] value = new char[length];
		for (int i = 0; i < length; i++) {
			value[i] = chs[random.nextInt(chs.length)];
		}
		final String code = new String(value);
		return code;
	}

	/**
	 * 通过正则验证手机号码是否正确
	 * @param str
	 * @return
	 */
	public static boolean isMobile(String str) {
        boolean b = false;
        Pattern p=Pattern.compile("^1(3|4|5|7|8)\\d{9}$");
        Matcher m = p.matcher(str);
        b = m.matches();
        return b;
	}

	/**
	 * 使用urlencode对链接进行编码
	 * @param url
	 * @return
	 */
	public static String urlEncode(String url){
		if(url == null || url.trim().equals(""))return null;
		try {
			return URLEncoder.encode(url, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 使用UrlDecode对链接进行解码
	 * @param url
	 * @return
	 */
	public static String urlDecode(String url){
		if(url == null || url.trim().equals(""))return null;
		try {
			return URLDecoder.decode(url, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}


	public static boolean isEmpty(String str){
		return (str == null || "".equals(str.trim()));
	}

	public static boolean isNotEmpty(String str){
		return (str != null && str.trim().length() > 0);
	}

	/**
	 * 判断文件是否是图片
	 * @param file
	 * @return
	 */
	public static boolean isImage(File file){
		if(file == null)return false;
		boolean flag = false;
		try {
			InputStream inputStream = new FileInputStream(file);
			flag = isImage(inputStream);
			inputStream.close();
		} catch (Exception e) {
		}
		return flag;
	}

	/**
	 * 判断输入流是否是图片
	 * @param inputStream
	 * @return
	 */
	public static boolean isImage(InputStream inputStream){
		boolean flag = false;
		try {
			BufferedImage Image=ImageIO.read(inputStream);
			if(null == Image) {
				return flag;
			}
			Image.flush();
			flag = true;
		} catch (Exception e){
		}
		return flag;
	}

    public static String getDate4Chinese(long timeInMillis){
    	long year_milliseconds = 31536000000L;
    	long day_milliseconds = 86400000L;
    	long hour_milliseconds = 3600000L;

    	String returnValue="";
    	Date now = new Date();
		long leftTime=now.getTime()-timeInMillis;

		long year = leftTime / year_milliseconds; // 这里必须加L，否则结果不对
		leftTime -= year*year_milliseconds;

		long day=leftTime/day_milliseconds;
		leftTime -= day*day_milliseconds;

		long hour=leftTime/hour_milliseconds;
		leftTime -= hour*hour_milliseconds;

		long minutes=(leftTime/(60*1000));
		leftTime -= minutes*60*1000;

		long second = leftTime/1000;

		if(year > 0){
			returnValue = year+"年";
		}
		if(day > 0){
			returnValue += day+"天";
		}

		if(StringUtils.isBlank(returnValue) && hour > 0){
			returnValue = hour+"小时";
		}
		if(StringUtils.isBlank(returnValue) && minutes > 0){
			returnValue = minutes+"分钟";
		}
		if(StringUtils.isBlank(returnValue)){
			returnValue = second+"秒";
		}

		return returnValue;
    }

    /**
     * 将输入流转成字符串
     * @param request
     * @return
     * @throws IOException
     */
    public static String parseHttpData(HttpServletRequest request) throws IOException{
    	//从request中取得输入流
    	InputStream inputStream=request.getInputStream();
    	String result = IOUtils.toString(inputStream, "UTF-8");
    	return result;
    }

	/**
	 * 获取客户端请求真实IP地址
	 */
	public static String getReqIpAddr(HttpServletRequest request) {
		String ip="";
		if(request!=null){
			ip = request.getHeader("x-forwarded-for");
		    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		        ip = request.getHeader("Proxy-Client-IP");
		    }
		    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		        ip = request.getHeader("WL-Proxy-Client-IP");
		    }
		    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		        ip = request.getRemoteAddr();
		 	}
		}
		return ip;
	}


    /**
     * 向URL中添加参数(有则修改，无则添加)
     * @param url
     * @param ParamName
     * @param ParamValue
     * @return
     */
	public static String addParamValue(String url, String ParamName, String ParamValue) {
        if(StringUtils.isNotBlank(url) && StringUtils.isNotBlank(ParamName) && StringUtils.isNotBlank(ParamValue)) {
            if(url.contains(ParamName+"=")){
            	url = replaceParamValue(url, ParamName, ParamValue);
            }else{
            	if(url.contains("?") || url.contains("\\?")){
                	url += "&"+ParamName+"=" + ParamValue;
                }else{
                	url += "?"+ParamName+"=" + ParamValue;
                }
            }
        }
        return url;
    }

    /**
     * 替换URL参数的值
     * @param url
     * @param ParamName
     * @param ParamValue
     * @return
     */
	public static String replaceParamValue(String url, String ParamName, String ParamValue) {
		if(StringUtils.isNotBlank(url) && StringUtils.isNotBlank(ParamName) && StringUtils.isNotBlank(ParamValue)) {
            url = url.replaceAll("(\\?" + ParamName +"=[^&]*)", "?"+ParamName + "=" + ParamValue);
            url = url.replaceAll("(\\&" + ParamName +"=[^&]*)", "&"+ParamName + "=" + ParamValue);
        }
        return url;
    }

	/**
	 * 删除URL中的参数
	 * @param url
	 * @param ParamName
	 * @return
	 */
	public static String removeParamValue(String url, String ParamName) {
        if(StringUtils.isNotBlank(url) && StringUtils.isNotBlank(ParamName)) {
        	while(url.contains("?"+ParamName+"=") || url.contains("%3f"+ParamName+"%3d") || url.contains("%3F"+ParamName+"%3D")
        		|| url.contains("&"+ParamName+"=") || url.contains("%26"+ParamName+"%3d") || url.contains("%26"+ParamName+"%3D")){
        		url = url.replaceAll("(\\?" + ParamName +"=[^&]*)", "");
            	url = url.replaceAll("(%3f" + ParamName +"%3d[^&]*)", "");
                url = url.replaceAll("(%3F" + ParamName +"%3D[^&]*)", "");

            	url = url.replaceAll("(\\&" + ParamName +"=[^&]*)", "");
            	url = url.replaceAll("(%26" + ParamName +"%3d[^&]*)", "");
                url = url.replaceAll("(%26" + ParamName +"%3D[^&]*)", "");
            }
        }
        return url;
    }

	/**
	 * 判断两域名是否是同一域下
	 * @param domain
	 * @param url
	 * @return
	 */
	public static boolean checkDomainMatched(String domain, String url){
		boolean result = false;
		if(StringUtils.isBlank(domain) || StringUtils.isBlank(url))return result;
		domain = domain.trim();
		url = url.trim();
		domain = domain.replace("/templates/index.html", "").replace("/index.htm", "").replace("templates/index.html", "").replace("index.htm", "");

		if(domain.startsWith("http://")){
			domain = domain.substring(7);
		}
		if(domain.startsWith("https://")){
			domain = domain.substring(8);
		}

		if(url.startsWith("http://")){
			url = url.substring(7);
		}
		if(url.startsWith("https://")){
			url = url.substring(8);
		}

		result = url.startsWith(domain);
		return result;
	}

	/**
	 * http链接转https
	 * @param url
	 * @return
	 */
	public static String httpTohttps(String url) {
		if(StringUtils.isBlank(url))return url;
		url = url.trim();
		if(url.startsWith("https:") || url.startsWith("HTTPS:"))return url;
		url = "https"+url.substring(4);
		return url;
	}

	/**
     * 使用BCrypt对密码进行加密
     * @param password
     * @return
     */
    public static String encryptPwdByBCrypt(String password){
    	return BCrypt.hashpw(password, BCrypt.gensalt());
    }

    /**
     * BCrypt 密码验证
     * @param password		明文
     * @param ciphertext	密文
     * @return	if equal ? true : false
     */
    public static boolean checkPwdByBCrypt(String password, String ciphertext){
    	return BCrypt.checkpw(password, ciphertext);
    }

    /**
     * 往cookie存值
     * @param response
     * @param name
     * @param value
     */
    public static void addCookie(HttpServletRequest request, HttpServletResponse response, String name, String value){
		addCookie(request, response, name, value, COOKIE_DEFAULT_MAXAGE);
	}

    /**
     * 往cookie存值
     * @param response
     * @param name
     * @param value
     * @param maxage
     */
	public static void addCookie(HttpServletRequest request, HttpServletResponse response, String name, String value, int maxage){
		String basePath = request.getContextPath();
		Cookie cookie = new Cookie(name, value);
		cookie.setPath(StringUtils.isBlank(basePath) ? "/" : basePath);
        cookie.setMaxAge(maxage > 0 ? maxage : COOKIE_DEFAULT_MAXAGE);
        response.addCookie(cookie);
	}

	/**
	 * 从cookie取值
	 * @param request
	 * @param cookieName
	 * @return
	 */
	public static String getValueFromCookie(HttpServletRequest request, String cookieName) {
		if(cookieName==null || cookieName.trim().equals(""))return null;
		Cookie[] cookies = request.getCookies();
		if (cookies != null && cookies.length > 0) {
			for (int i = 0; i < cookies.length; i++) {
				Cookie item = cookies[i];
				String name = item.getName();
				if (cookieName.equals(name)) {
					return item.getValue();
				}
			}
		}
		return null;
	}

	/**
	 * 输出错误信息到页面
	 * @param response
	 * @param title 网页title
	 * @param result 内容
	 */
	public static void outPrintError(HttpServletResponse response, String title, String result){
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = null;
		try {
			if(StringUtils.isBlank(title))title = "Error";
			String html = "<!DOCTYPE html><html><head>";
			html += "<title>"+title+"</title>";
			html += "<meta charset=\"utf-8\">";
			html += "<meta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1\">";
			html += "</head><body>";
			html+="<center><div style=\"width:85%; text-align:center; font-size: 18px; line-height:35px; color: red;\">";
			html += result;
			html+="</div></center></body></html>";
			out = response.getWriter();
			out.print(html);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("IO工作流出现异常!");
		} finally {
			if(out!=null){
				out.close();
				out = null;
			}
		}
	}

    public static void main(String[] args) {
		String url = httpTohttps("http://wx.qlogo.cn/mmopen/tolX9TNpO");
    	System.out.println("url = "+url);

	}

}
