package com.yingying.tourist.common;


import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class Util {
	
	private static Random random = new Random();

	public static String getRandomFromVector(Vector<String> source) {
		// now we select a prefix randomly
		int prefixSetSize = source.size();
		int prefixIndex = (int) (Math.random() * prefixSetSize);
		String prefixString = source.get(prefixIndex);
		return prefixString;
	}

	public static int getRandomIntFromVector(Vector<Integer> source) {
		// now we select a prefix randomly
		int prefixSetSize = source.size();
		int prefixIndex = (int) (Math.random() * prefixSetSize);
		int myInt = source.get(prefixIndex);
		return myInt;
	}

	public static String getRandomFromArray(String[] source) {
		// now we select a prefix randomly
		int prefixSetSize = source.length;
		int prefixIndex = (int) (Math.random() * prefixSetSize);
		String prefixString = source[prefixIndex];
		return prefixString;
	}

	public static int getRandomInt(int start, int end) {
		int rangeSize = end - start;
		return random.nextInt(rangeSize) + start;
	}
	
	/**
	 * 返回一个随机正数
	 * @return
	 */
	public static int getRandomInt() {
		int randomInt = random.nextInt();
		if (randomInt == Integer.MIN_VALUE) {
			return Integer.MAX_VALUE;
		}else {
			return Math.abs(randomInt);
		}
	}
	
	/**
	 * 
	 * @param start	包含
	 * @param end	不包含
	 * @return
	 */
	public static int getRandomInteger(int start, int end) {
		int rangeSize = end - start;
		int index = (int) (Math.random() * rangeSize) + start;
		return index;
	}

	public static long getRandomLong(long start, long end) {
		long rangeSize = end - start;
		long index = (long) (Math.random() * rangeSize) + start;
		return index;
	}

	public static String getRandomDate(String beginDateString,
			String endDateString) {

		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

			Date beginDate = sdf.parse(beginDateString);
			Date endDate = sdf.parse(endDateString);

			long timeRange = (endDate.getTime() - beginDate.getTime());

			long millisecondAdd = (long) (Math.random() * timeRange);

			Date randomDate = new java.sql.Date(beginDate.getTime()
					+ millisecondAdd);

			return randomDate.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// prob has same size as source
	public static Object getRandomObjectByProb(Object[] source, int[] prob) {

		// now we select a prefix randomly
		int sourceSetSize = source.length;
		int sumWeight = 0;
		int i = 0;
		for (i = 0; i < sourceSetSize; i++) {
			sumWeight += prob[i];
			// System.out.println("in " + i + ":" + source[i] + ":" + prob[i]);
		}
		int[] accumulation = new int[sourceSetSize + 1];

		accumulation[0] = 0;
		accumulation[sourceSetSize] = sumWeight;
		int index = 1;
		while (index < sourceSetSize) {
			accumulation[index] = accumulation[index - 1] + prob[index - 1];
			// System.out.println("in2 " + index + ":" + accumulation[index]);
			index++;
		}
		int random100 = (int) (Math.random() * sumWeight);
		// System.out.println("random100 : " + random100);
		index = 0;

		while (index < sourceSetSize) {
			if ((accumulation[index] <= random100)
					&& (random100 < accumulation[index + 1])) {
				return source[index];
			}
			index++;
		}

		return null;
	}

	public static String getRandomDigitString(int length) {
		StringBuilder suffixString = new StringBuilder();
		int i = 0;
		for (i = 0; i < length; i++) {
			suffixString.append((int) (Math.random() * 10));
		}
		return suffixString.toString();
	}

	public static int getRandomIntFromHashMap(HashMap<Integer, Integer> source) {
		int size = source.size();
		Integer[] idArray = new Integer[size];
		int[] valueArray = new int[size];

		Iterator<Integer> iter = source.keySet().iterator();
		int index = 0;
		while (iter.hasNext()) {
			int id = iter.next();
			int value = source.get(id);
			idArray[index] = id;
			valueArray[index] = value;
			// System.out.println(index + ":" + id + ":" + value);
			index++;
		}
		Integer returnInt = (Integer) getRandomObjectByProb(idArray, valueArray);
		return returnInt;
	}

	public static int getAge(String birthDay) {
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			Date d = df.parse(birthDay);
			Date nowDate = new Date();
			return (int) ((nowDate.getTime() - d.getTime()) / ((long) 365 * 24 * 60 * 60 * 1000));

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

	public static int getAge(Date birthDay) {
		Date nowDate = new Date();
		return (int) ((nowDate.getTime() - birthDay.getTime()) / ((long) 365 * 24 * 60 * 60 * 1000));
	}

	// to replace the parameter like ${1} in the string by value
	public static String replaceParameter(String source, Vector<String> values) {
		String result = source;
		for (int i = 0; i < values.size(); i++) {
			// System.out.println("${"+(i+1)+"}"+ " : " + values.get(i));
			String value = (String) (values.get(i));
			if ((value.startsWith("[")) && (value.endsWith("]"))) {
				value = value.substring(1, value.length() - 1);
			}
			if ((value.startsWith("(")) && (value.endsWith(")"))) {
				value = value.substring(1, value.length() - 1);
			}
			if (value.startsWith("\\")) {
				value = value.substring(1);
			}
			result = result.replaceAll("\\$\\{" + (i + 1) + "\\}", value);
		}
		return result;
	}

	public static String readStringFromFile(String inputFilename) {
		File file = new File(inputFilename);
		BufferedReader reader = null;
		StringBuilder tempString = new StringBuilder();
		try {

			reader = new BufferedReader(new FileReader(file));
			String line = null;
			while ((line = reader.readLine()) != null) {
				tempString.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		return tempString.toString();
	}

	public static String getRandomDateByAge(int age) {
		long addDay = (((long) (age - 1)) * 365) + getRandomInt(1, 365);
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			Date d = df.parse("2012-08-18");
			Date newDate = new Date(d.getTime()
					- (((long) addDay) * 24 * 60 * 60 * 1000));
			//
			return df.format(newDate);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static boolean isLeapYear(int year) {

		GregorianCalendar calendar = new GregorianCalendar();

		return calendar.isLeapYear(year);

	}

	public static void saveToFile(String destUrl, String fileName) {
		try {
			FileOutputStream fos = null;
			BufferedInputStream bis = null;
			HttpURLConnection httpconn = null;
			URL url = null;
			int BUFFER_SIZE = 4096;

			byte[] buf = new byte[BUFFER_SIZE];
			int size = 0;

			// 建立链接
			url = new URL(destUrl);
			httpconn = (HttpURLConnection) url.openConnection();
			// 连接指定的资源
			httpconn.connect();
			// 获取网络输入流
			bis = new BufferedInputStream(httpconn.getInputStream());
			// 建立文件

			fos = new FileOutputStream(fileName);

			System.out.println("正在获取链接[" + destUrl + "]的内容\n将其保存为文件["
					+ fileName + "]");

			// 保存文件
			while ((size = bis.read(buf)) != -1)
				fos.write(buf, 0, size);
			fos.close();
			bis.close();
			httpconn.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String sideTrim(String stream, String trimstr) {

		// null或者空字符串的时候不处理
		if (stream == null || stream.length() == 0 || trimstr == null
				|| trimstr.length() == 0) {
			return stream;
		}

		// 结束位置
		int epos = 0;

		// 正规表达式
		String regpattern = "[" + trimstr + "]*+";
		Pattern pattern = Pattern.compile(regpattern, Pattern.CASE_INSENSITIVE);

		// 去掉结尾的指定字符
		StringBuffer buffer = new StringBuffer(stream).reverse();
		Matcher matcher = pattern.matcher(buffer);
		if (matcher.lookingAt()) {
			epos = matcher.end();
			stream = new StringBuffer(buffer.substring(epos)).reverse()
					.toString();
		}

		// 去掉开头的指定字符
		matcher = pattern.matcher(stream);
		if (matcher.lookingAt()) {
			epos = matcher.end();
			stream = stream.substring(epos);
		}

		// 返回处理后的字符串
		return stream;
	}

	public static int BKDRHash(String str) {

		int seed = 131; // 31 131 1313 13131 131313 etc..
		int hash = 0;

		for (int i = 0; i < str.length(); i++) {

			hash = (hash * seed) + str.charAt(i);
		}
		return (hash & 0x7FFFFFFF);
	}

	public static boolean emailFormat(String email) {
		boolean tag = true;
		final String pattern1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
		final Pattern pattern = Pattern.compile(pattern1);
		final Matcher mat = pattern.matcher(email);
		if (!mat.find()) {
			tag = false;
		}
		return tag;
	}

	public static String removeLinkTags(String content) {
		if (content != null && !("").equals(content)) {
			Pattern p = Pattern.compile("<a.*?/a>");
			Matcher m = p.matcher(content);
			while (m.find()) {
				Matcher href = Pattern.compile("href=.*? ").matcher(m.group());
				while (href.find()) {
					String url = href.group().replaceAll("href=|\"|>", "");
					content = content.replaceAll(m.group(), url);
				}
			}
		}
		return content;
	}

	/**
	 * 统计字串在源字符串中出现的次数
	 *
	 * @param origStr
	 *            源字符串
	 * @param subStr
	 *            子串
	 * @return 字串出现的次数
	 */
	public static int countSubStr(String origStr, String subStr) {
		int count = 0;
		if (origStr != null && !("").equals(origStr) && subStr != null
				&& !("").equals(subStr)) {
			int index = 0;
			while ((index = origStr.indexOf(subStr, index)) != -1) {
				count++;
				index += subStr.length();
			}
		}
		return count;
	}

	public static boolean isNull(Object argObj) {

		if (argObj == null) {
			return true;
		}

		if (argObj instanceof String) {

			if (((String) argObj).trim().equals("")
					|| ((String) argObj).trim().equals(" ")
					|| ((String) argObj).trim().equals("null")) {
				return true;
			}
		}

		if (argObj instanceof Collection) {

			if (((Collection) argObj).size() == 0) {
				return true;
			}
		}

		if (argObj instanceof Map) {

			if (((Map) argObj).size() == 0) {
				return true;
			}
		}

		return false;
	}

	public static boolean isNotNull(Object argObj) {
		return !Util.isNull(argObj);
	}

	public static Integer[] parseInt(String[] str) {
		Integer temp[] = new Integer[str.length];
		for (int i = 0; i < str.length; i++) {
			temp[i] = Integer.parseInt(str[i].replace("[", "").replace("]", "")
					.trim());
		}
		return temp;
	}

	public static int[] showPage(int page, int lastpage) {
		int k[];
		if (lastpage <= 10) {
			k = new int[lastpage];
			for (int i = 0; i < lastpage; i++) {
				k[i] = i + 1;
			}
		} else if (page + 10 > lastpage) {
			k = new int[10];
			for (int i = 0; i < 10; i++) {
				k[i] = lastpage - 10 + i + 1;
			}
		} else if (page + 10 <= lastpage && page < 7) {
			k = new int[10];
			for (int i = 0; i < 10; i++) {
				k[i] = i + 1;
			}
		} else if (page + 10 <= lastpage && page >= 7) {
			k = new int[10];
			for (int i = 0; i < 10; i++) {
				k[i] = page - 5 + i;
			}
		} else {
			k = new int[10];
		}
		return k;
	}

	// 获取数组不同数据
	public static List getNoNum(String[] a, String[] b) {
		List list = new ArrayList();
		if (Util.isNull(b)) {
			for (int i = 0; i < a.length; i++) {
				list.add(a[i]);
			}
		} else {
			String[] la = a;
			String[] lb = b;
			for (int i = 0; i < la.length; i++) {
				boolean boo = false;
				for (int j = 0; j < lb.length; j++) {
					if (la[i].equals(lb[j])) {
						boo = true;
						break;
					}
				}
				if (!boo) {
					list.add(la[i]);
				}
			}
		}
		return list;
	}

	/**
     * 获取用户ip地址
     * */
    public static String getIpAddress(HttpServletRequest request) {

        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                // 根据网卡取本机配置的IP
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress = inetAddress.getHostAddress();
            }
        }
        /*
         * 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
         * 单个ip的长度为15，格式：***.***.***.***
         * */
        if (ipAddress != null && ipAddress.length() > 15 && ipAddress.indexOf(",") > 0) {
            ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
        }
        return ipAddress;

    }


	/**
	 * 获取客户端IP
	 *
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String 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;
	}

	/**
	 * 1. byte(8位有符号)的取值范围是 -128-127, char(16位无符号)的取值范围是0-65535;<BR>
	 * 2.如果一个byte对应的十六进制数只有一位前面要用0填充，因为MD5是32位的，达到统一的格式<BR>
	 * 3.0x是十六进制的标示，比如：0xFF表示8位的二进制1111 1111;0x00FF表示16位的二进制0000 0000 1111 1111
	 * */
	public static String getSHA_1Mask(String str) {
		MessageDigest messageDigest = null;
		try {
			messageDigest = MessageDigest.getInstance("SHA-1");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
			byte[] byteArray = messageDigest.digest();
			StringBuffer md5StrBuff = new StringBuffer();
			for (int i = 0; i < byteArray.length; i++) {
				if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
					md5StrBuff.append("0").append(
							Integer.toHexString(0xFF & byteArray[i]));
				else
					md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
			}
			return md5StrBuff.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	/**
	 * 过滤html标签
	 *
	 * @param inputString
	 * @return
	 */
	public static String html2Text(String inputString) {
		String htmlStr = inputString; // 含html标签的字符串
		String textStr = "";
		Pattern p_script;
		Matcher m_script;
		Pattern p_style;
		Matcher m_style;
		Pattern p_html;
		Matcher m_html;
		Pattern p_html1;
		Matcher m_html1;

		try {
			String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
			String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
			String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
			String regEx_html1 = "<[^>]+";

			p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
			m_script = p_script.matcher(htmlStr);
			htmlStr = m_script.replaceAll(""); // 过滤script标签

			p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
			m_style = p_style.matcher(htmlStr);
			htmlStr = m_style.replaceAll(""); // 过滤style标签

			p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
			m_html = p_html.matcher(htmlStr);
			htmlStr = m_html.replaceAll(""); // 过滤html标签

			p_html1 = Pattern.compile(regEx_html1, Pattern.CASE_INSENSITIVE);
			m_html1 = p_html1.matcher(htmlStr);
			htmlStr = m_html1.replaceAll(""); // 过滤html标签
			textStr = htmlStr;

		} catch (Exception e) {
			System.err.println("Html2Text: " + e.getMessage());
		}

		return textStr;// 返回文本字符串
	}

	/**
	 * 过滤html标签 保留A标签
	 *
	 * @param inputString
	 * @return
	 */
	public static String filterHtml2Text(String inputString) {
		String htmlStr = inputString; // 含html标签的字符串
		String textStr = "";
		Pattern p_script;
		Matcher m_script;
		Pattern p_style;
		Matcher m_style;
		Pattern p_html;
		Matcher m_html;

		try {
			String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
			String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
			String regEx_html = "(<\\/(?![aA])[a-zA-Z]+>)|(<(?![aA])[ ]?[^\\/>]+>)";//(<(?![aA])[ ]?[^\\/>]+>)

			p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
			m_script = p_script.matcher(htmlStr);
			htmlStr = m_script.replaceAll(""); // 过滤script标签

			p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
			m_style = p_style.matcher(htmlStr);
			htmlStr = m_style.replaceAll(""); // 过滤style标签

			p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
			m_html = p_html.matcher(htmlStr);
			htmlStr = m_html.replaceAll(""); // 过滤html标签

//			p_html1 = Pattern.compile(regEx_html1, Pattern.CASE_INSENSITIVE);
//			m_html1 = p_html1.matcher(htmlStr);
//			htmlStr = m_html1.replaceAll(""); // 过滤html标签
			textStr = htmlStr;

		} catch (Exception e) {
			System.err.println("Html2Text: " + e.getMessage());
		}

		return textStr;// 返回文本字符串
	}
	
 

	/**
	 * 截取省略
	 * 
	 * @param content
	 *            内容
	 * @param len
	 *            长度
	 * @return 截取后的长度
	 */
	public static String cutOmit(String content, int len) {
		if (content != null && !("").equals(content.trim())) {
			if (content.length() > len) {
				String subStr = content.substring(0, len - 1);
				content = subStr.concat("...");
			}
		}
		return content;
	}

	public static String SpecialCharactersFilter(String content) {
		String filterCharacters = "[!@#$%^&*()_+-=,. /?']";
		content = content.replaceAll(filterCharacters, "");
		// http :// www.baidu.com or 192.168.1.1 :8080 a/ x. html ?dd #maodian
		// String scriptString =
		// "(?<!(href=\"|>))((?:http[s]?|ftp)://)([^:\"<\\s]+|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})(:\\d+)?(?:((?:\\w+)*/)([\\w\\-\\.]+[^><\"#?\\s]+)?(\\?[^\\s#]*)?(#\\w+)?)?";
		// Pattern p_script = Pattern.compile(scriptString,
		// Pattern.CASE_INSENSITIVE);
		// Matcher m_script = p_script.matcher(content);
		//
		// while (m_script.find()) {
		// String f = m_script.group();
		// System.out.println(f);
		// }

		return content;
	}

	// base64加密
	public static String base64_encodeStr(String plainText) {
		byte[] b = plainText.getBytes();
		Base64 base64 = new Base64();
		b = base64.encode(b);
		String s = new String(b);
		return s;
	}

	// base64解密
	public static String base64_decodeStr(String encodeStr) {
		byte[] b = encodeStr.getBytes();
		Base64 base64 = new Base64();
		b = base64.decode(b);
		String s = new String(b);
		return s;
	}


	/**
	 * 比当今时间大，返回1 比当今时间小，返回-1 跟当今时间相同，返回0
	 * 
	 * @param date
	 * @param keepTime 单位
	 *            ：秒
	 * @return
	 */
	public static int compareWithCurrentTime(Date date, int keepTime) {
		// 秒转为毫秒
		keepTime *= 1000;
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int i = 0;
		long l = c.getTimeInMillis() + keepTime - System.currentTimeMillis();
		if (l > 0) {
			i = 1;
		} else if (l < 0) {
			i = -1;
		} else {
			i = 0;
		}

		return i;
	}

	public static int getDayCount(int year, int month) {
		int result = 0;
		if (1 == month || 3 == month || 5 == month || 7 == month || 8 == month
				|| 10 == month || 12 == month) {
			result = 31;
		} else if (4 == month || 6 == month || 9 == month || 11 == month) {
			result = 30;
		} else if (2 == month) {
			if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
				result = 29;
			} else {
				result = 28;
			}
		}
		return result;
	}

	public static String getSubStrLen(String str, int len) {
		String result = "";
		if (str.length() > len) {
			result = str.substring(0, len) + "...";
		} else {
			result = str;
		}
		return result;
	}

	 
	
    /**
     * Filter the specified string for characters that are sensitive to
     * HTML interpreters, returning the string with these characters replaced
     * by the corresponding character entities.
     *
     * @param value The string to be filtered and returned
     */
    public static String filter(String value) {

        if (value == null || value.length() == 0) {
            return value;
        }

        StringBuilder result = null;
        String filtered = null;
        for (int i = 0; i < value.length(); i++) {
            filtered = null;
            switch (value.charAt(i)) {
                case '<':
                    filtered = "&lt;";
                    break;
                case '>':
                    filtered = "&gt;";
                    break;
                case '&':
                    filtered = "&amp;";
                    break;
                case '"':
                    filtered = "&quot;";
                    break;
                case '\'':
                    filtered = "&#39;";
                    break;
            }

            if (result == null) {
                if (filtered != null) {
                    result = new StringBuilder(value.length() + 50);
                    if (i > 0) {
                        result.append(value.substring(0, i));
                    }
                    result.append(filtered);
                }
            } else {
                if (filtered == null) {
                    result.append(value.charAt(i));
                } else {
                    result.append(filtered);
                }
            }
        }

        return result == null ? value : result.toString();
    }
    
    public static String regexpFilter(String s) {
		if (s == null) {
			return "";
		}
		
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
			case '(':
				sb.append("\\(");
				break;
			case ')':
				sb.append("\\)");
				break;
			case '*':
				sb.append("\\*");
				break;
			case '?':
				sb.append("\\?");
				break;
			case '+':
				sb.append("\\+");
				break;
			case '.':
				sb.append("\\.");
				break;
			case '^':
				sb.append("\\^");
				break;
			case '[':
				sb.append("\\[");
				break;
			case ']':
				sb.append("\\]");
				break;
			case '\\':
				sb.append("\\\\");
				break;
			case '|':
				sb.append("\\|");
				break;
			case '{':
				sb.append("\\{");
				break;
			case '}':
				sb.append("\\}");
				break;
			case '/':
				sb.append("\\/");
				break;
			default:
				sb.append(c);
			}
		}
		return sb.toString();
	}
    

	public static String string2Json(String s) {
		if (s == null) {
			return "";
		}
		
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\"':
				sb.append("\\\"");
				break;
			case '\\':
				sb.append("\\\\");
				break;
//			case '/':
//				sb.append("\\/");
//				break;
			case '\b':
				sb.append("\\b");
				break;
			case '\f':
				sb.append("\\f");
				break;
			case '\n':
				sb.append("\\n");
				break;
			case '\r':
				sb.append("\\r");
				break;
			case '\t':
				sb.append("\\t");
				break;
			default:
				sb.append(c);
			}
		}
		return sb.toString();
	}  
    

	
	 
	 
	
	
	 /**
     * sql转义
     *
     * @param value The string to be filtered and returned
     */
    public static String sqlEscape(String value) {

    	if (Util.isNull(value)) {
            return value;
        }
        return value.replaceAll("\\\\", "").replaceAll("'", "''").replaceAll("/", "//").replaceAll("%", "/%")
        		.replaceAll("_", "/_");
    }
    
    /**
     * spifix转义
     *
     * @param value The string to be filtered and returned
     */
    public static String spEscape(String value) {

    	if (Util.isNull(value)) {
            return value;
        }
        return value.replace("$", "").replace("^", "");
    }
    
    /**
     * 计算字数 汉字算1个 英文字算半个 向上取整
     * @param str
     * @return
     */
    public static int countWords(String str) {
        if (str == null || str.length() <= 0) {
            return 0;
        }
        float len = 0;
        char c;
        for (int i = str.length() - 1; i >= 0; i--) {
            c = str.charAt(i);
            if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
                // 字母, 数字
                len+=0.5;
            } else {
                if (Character.isLetter(c)) { // 中文
                    len++;
                } else { // 符号或控制字符
                    len+=0.5;
                }
            }
        }
        return (int)(len + 0.5);//
    }
    
    /**
     * 获取字符串的长度，中文占一个字符,英文数字占半个字符
     *
     * @param value  指定的字符串          
     * @return 字符串的长度
     */
    public static int realLength(String value) {
        double valueLength = 0;
        String chinese = "[\u4e00-\u9fa5]";
        // 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
        for (int i = 0; i < value.length(); i++) {
            // 获取一个字符
            String temp = value.substring(i, i + 1);
            // 判断是否为中文字符
            if (temp.matches(chinese)) {
                // 中文字符长度为1
                valueLength += 1;
            } else {
                // 其他字符长度为0.5
                valueLength += 0.5;
            }
        }
        //进位取整
        return  (int)Math.floor(valueLength);
    }
    
  //取得文件大小
  	public static long getFileSizes(File f) throws Exception{
          long s=0;
          if (f.exists()) {
              FileInputStream fis = null;
              fis = new FileInputStream(f);
              s= fis.available();
              fis.close();
          } else {
              System.out.println("文件不存在");
          }
          return s;
      }
    
   //取得文件夹大小
	public static long getFileSize(File f) throws Exception{
		long size = 0;
		if (f.exists()) {
			File flist[] = f.listFiles();
	        for (int i = 0; i < flist.length; i++)
	        {
	            if (flist[i].isDirectory())
	            {
	                size = size + getFileSize(flist[i]);
	            } else
	            {
	                size = size + flist[i].length();
	            }
	        }
		}
        return size;
    }
	
	
    /**
     * 字符串数组转字符串
     *
     * value The string to be filtered and returned
     */
    public static String toString(String mids[]) {

    	if (Util.isNull(mids)) {
            return null;
        }
    	StringBuffer s = new StringBuffer();
    	for (int i=0;i<mids.length;i++) {
    		s.append(mids[i]+",");
    	}
        return s.toString().substring(0, s.toString().length()-1);
    }
    
    public static boolean isSame(String array[]) {
	    for(int i=0; i<array.length; i++){
	        for(int j=i+1; j<array.length;j++){
	            if(array[i].equals(array[j])){
	                return false;
	            }
	        }
	    }
	    return true;
    }
    
    
    public static String arrayToStr(String array[]) {
	    if (Util.isNull(array)) return null;
	    StringBuffer sb = new StringBuffer();
	    for (int i=0;i<array.length;i++) {
	    	sb.append(array[i]+",");
	    }
	    return sb.toString().substring(0, sb.toString().length()-1);
    }
    
    
	 
	
	/**
	 * 1. byte(8位有符号)的取值范围是 -128-127, char(16位无符号)的取值范围是0-65535;<BR>
	 * 2.如果一个byte对应的十六进制数只有一位前面要用0填充，因为MD5是32位的，达到统一的格式<BR>
	 * 3.0x是十六进制的标示，比如：0xFF表示8位的二进制1111 1111;0x00FF表示16位的二进制0000 0000 1111 1111
	 * */
	public static String getMD5(String str) {
		MessageDigest messageDigest = null;
		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
			byte[] byteArray = messageDigest.digest();
			StringBuffer md5StrBuff = new StringBuffer();
			for (int i = 0; i < byteArray.length; i++) {
				if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
					md5StrBuff.append("0").append(
							Integer.toHexString(0xFF & byteArray[i]));
				else
					md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
			}
			return md5StrBuff.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
	
	/**
	 * 与python join的方法一样
	 * @param list
	 * @return
	 */
	public static String join(String[] list){
		if (Util.isNull(list)) {
			return "";
		}
		StringBuilder sb = new StringBuilder();
		for (String string : list) {
			sb.append(",").append(string).append("");
		}
		sb.deleteCharAt(0);
		return sb.toString();
	}
	
	/**
	 * 获取随机字符串
	 * @param length
	 * @return
	 */
	public static String CreateRandomStr(int length) {
		String val = "";  
        Random random = new Random();        
        //length为几位密码 
        for(int i = 0; i < length; i++) {          
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";  
            //输出字母还是数字  
            if( "char".equalsIgnoreCase(charOrNum) ) {  
                //输出是大写字母还是小写字母  
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;  
                val += (char)(random.nextInt(26) + temp);  
            } else if( "num".equalsIgnoreCase(charOrNum) ) {  
                val += String.valueOf(random.nextInt(10));  
            }  
        }  
        //去掉 字母O大小写和数字0
        if(val.contains("o") || val.contains("O") || val.contains("0")){
        	val = CreateRandomStr(length);
        }
        return val; 
	}
	
	/**
	 * 将cookie封装到Map里面
	 * @param request
	 * @return
	 */
	public static Map<String,Cookie> ReadCookieMap(HttpServletRequest request){
	    Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
	    Cookie[] cookies = request.getCookies();
	    if(null!=cookies){
	        for(Cookie cookie : cookies){
	            cookieMap.put(cookie.getName(), cookie);
	        }
	    }
	    return cookieMap;
	}
	
	/**
	 * 根据key获取cookie值
	 * @author liushiming
	 * @param request
	 * @param key
	 * @return
	 */
	public static String readCookieByKey(HttpServletRequest request, String key){
		String cookie_code = "";
		try {
		    Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
		    Cookie[] cookies = request.getCookies();
		    if(null!=cookies){
		        for(Cookie cookie : cookies){
		            cookieMap.put(cookie.getName(), cookie);
		        }
		    }
		    if (cookieMap.containsKey(key)){
				Cookie cookie = cookieMap.get(key);
				cookie_code = java.net.URLDecoder.decode(cookie.getValue(),"UTF-8");
		    }
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return cookie_code;
	}
	
	
	public static String arrayToString(Object[] object) {
		StringBuffer buffer = new StringBuffer("[");
		for (Object obj : object) {
			buffer.append(String.valueOf(obj)).append(",");
		}
		buffer.delete(buffer.length() - 1, buffer.length());
		buffer.append("]");
		return buffer.toString();
	}

	
	public static Integer getIntMapValue(Map map,String key){
		Object o = map.get(key);
		if(isNull(o)){
			return null;
		}
		return Integer.valueOf(o.toString());
	}
	
	public static void putStrToMap(Map map,String key,String value){
		//is not null
		if (value != null && !value.trim().equals("") && !value.trim().equals(" ") && !value.trim().equals("null")) {
			map.put(key, value);
		}
	}
	
	public static void putIntToMap(Map map,String key,Integer value){
		//is not null
		 if(value != null)
			 map.put(key, value);
	}
	
	/**
	 * 将非空对象put进map中
	 * @param map
	 * @param key
	 * @param value
	 */
	public static void putToMap(Map map,String key,Object value){
		if (!isNull(value)) {
			map.put(key, value);
		}
	}

	/**
	 * 如果为空，返回空字符
	 * */
    public static String getStringByObject(Object source){
        if (Util.isNull(source)){
            return "";
        } else {
            return source.toString();
        }
    }
    
    /**
     * 如果为空，返回 null
     * */
    public static String getNullOrStringByObject(Object source) {
        if (Util.isNull(source)) {
            return null;
        } else {
            return source.toString();
        }
    }

    /**
     * 如果为空，返回 0
     * */
    public static Integer getIntegerByObject(Object source){
        if (Util.isNull(source)){
            return 0;
        } else {
            try {
                return Integer.parseInt(source.toString());
            } catch (Exception e) {
                return 0;
            }
        }
    }

    /**
     * 如果为空，返回 null
     * */
    public static Integer getNullOrIntegerByObject(Object source){
        if (Util.isNull(source)){
            return null;
        } else {
            try {
                return Integer.parseInt(source.toString());
            } catch (Exception e) {
                return null;
            }
        }
    }

	public static Long getLongByObject(Object source){
		if (Util.isNull(source)){
			return 0L;
		} else {
			try {
				return Long.parseLong(source.toString());
			} catch (Exception e) {
				return 0L;
			}
		}
	}

	/**
	 * 如果为空，返回 null
	 * */
	public static Long getNullOrLongByObject(Object source){
		if (Util.isNull(source)){
			return null;
		} else {
			try {
				return Long.parseLong(source.toString());
			} catch (Exception e) {
				return null;
			}
		}
	}
    
    /**
     * 保留两位小数（如果为空，返回 0.0）
     * */
    public static Double getDoubleByObject(Object source){
        if (Util.isNull(source)){
            return 0.0;
        } else {
            try {
                double db = Double.parseDouble(source.toString());
                BigDecimal b = new BigDecimal(db);
                return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            } catch (Exception e) {
                return 0.0;
            }
        }
    }
    
    /**
     * 保留两位小数（如果为空，返回 null）
     * */
    public static Double getNullOrDoubleByObject(Object source) {
        if (Util.isNull(source)){
            return null;
        } else {
            try {
                double db = Double.parseDouble(source.toString());
                BigDecimal b = new BigDecimal(db);
                return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            } catch (Exception e) {
                return null;
            }
        }
    }
    
    /**
     * 字符替换
     * @author liuyu
     * @param source
     * @param exist 执行替换的条件（该字符是否存在）
     * @param regex 被替换的字符
     * @param replacement 替换为
     * */
    public static String replaceAll (String source, String exist, String regex, String replacement) {
        String result = source;
        if (source.indexOf(exist) >= 0) {
            result = source.replaceAll(regex, replacement);
        }
        return result;
    }

    /**
     * 获取定长位数随机数字
     * 
     * @param length
     *            位数
     * @return 定长位数随机字符
     */
    public static String getRandomMath(int length) { // length表示生成字符串的长度
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    
    /**
     * @Description: 将base64编码字符串转换为图片
     * @Author: 
     * @CreateTime: 
     * @param imgStr base64编码字符串
     * path 图片路径-具体到文件
     * @return
    */
    public static InputStream generateImage(String imgStr) {
	    if (imgStr == null)
	    	throw new IllegalArgumentException("参数不存在");
	    InputStream input = null;
	    BASE64Decoder decoder = new BASE64Decoder();
	    try {
		    // 解密
		    byte[] b = decoder.decodeBuffer(imgStr);
		    // 处理数据
		    for (int i = 0; i < b.length; ++i) {
			    if (b[i] < 0) {
			    	b[i] += 256;
			    }
		    }
		    input = new ByteArrayInputStream(b);
	    } catch (Exception e) {
	    	e.printStackTrace();
	    }
	    return input;
    }

	/**
	 *  拆分List为指定大小的多个List
	 * @param resList
	 * @param count
	 * @param <T>
	 * @return
	 */
	public static  <T> List<List<T>> splitList(List<T> resList,int count){

		if(resList==null ||count<1){
			return  null ;
		}
		List<List<T>> ret=new ArrayList<List<T>>();
		int size=resList.size();
		//数据量不足count指定的大小
		if(size<=count){
			ret.add(resList);
		}else{
			int pre=size/count;
			int last=size%count;
			//前面pre个集合，每个大小都是count个元素
			for(int i=0;i<pre;i++){
				List<T> itemList=new ArrayList<T>();
				for(int j=0;j<count;j++){
					itemList.add(resList.get(i*count+j));
				}
				ret.add(itemList);
			}
			//last的进行处理
			if(last>0){
				List<T> itemList=new ArrayList<T>();
				for(int i=0;i<last;i++){
					itemList.add(resList.get(pre*count+i));
				}
				ret.add(itemList);
			}
		}
		return ret;

	}

    public static boolean isMobileDevice(HttpServletRequest request){
        /**Wap网关Via头信息中特有的描述信息*/
        String mobileGateWayHeaders[]=new String[]{
                "ZXWAP",//中兴提供的wap网关的via信息，例如：Via=ZXWAP GateWayZTE Technologies，
                "chinamobile.com",//中国移动的诺基亚wap网关，例如：Via=WTP/1.1 GDSZ-PB-GW003-WAP07.gd.chinamobile.com (Nokia WAP Gateway 4.1 CD1/ECD13_D/4.1.04)
                "monternet.com",//移动梦网的网关，例如：Via=WTP/1.1 BJBJ-PS-WAP1-GW08.bj1.monternet.com. (Nokia WAP Gateway 4.1 CD1/ECD13_E/4.1.05)
                "infoX",//华为提供的wap网关，例如：Via=HTTP/1.1 GDGZ-PS-GW011-WAP2 (infoX-WISG Huawei Technologies)，或Via=infoX WAP Gateway V300R001 Huawei Technologies
                "XMS 724Solutions HTG",//国外电信运营商的wap网关，不知道是哪一家
                "wap.lizongbo.com",//自己测试时模拟的头信息
                "Bytemobile",//貌似是一个给移动互联网提供解决方案提高网络运行效率的，例如：Via=1.1 Bytemobile OSN WebProxy/5.1
        };
        /**电脑上的IE或Firefox浏览器等的User-Agent关键词*/
        String[] pcHeaders=new String[]{
                "Windows 98",
                "Windows ME",
                "Windows 2000",
                "Windows XP",
                "Windows NT",
                "Ubuntu"
        };
        /**手机浏览器的User-Agent里的关键词*/
        String[] mobileUserAgents=new String[]{
                "Nokia",//诺基亚，有山寨机也写这个的，总还算是手机，Mozilla/5.0 (Nokia5800 XpressMusic)UC AppleWebkit(like Gecko) Safari/530
                "SAMSUNG",//三星手机 SAMSUNG-GT-B7722/1.0+SHP/VPP/R5+Dolfin/1.5+Nextreaming+SMM-MMS/1.2.0+profile/MIDP-2.1+configuration/CLDC-1.1
                "MIDP-2",//j2me2.0，Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1 /110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML like Gecko) Safari/413
                "CLDC1.1",//M600/MIDP2.0/CLDC1.1/Screen-240X320
                "SymbianOS",//塞班系统的，
                "MAUI",//MTK山寨机默认ua
                "UNTRUSTED/1.0",//疑似山寨机的ua，基本可以确定还是手机
                "Windows CE",//Windows CE，Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)
                "iPhone",//iPhone是否也转wap？不管它，先区分出来再说。Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; zh-cn) AppleWebKit/532.9 (KHTML like Gecko) Mobile/8B117
                "iPad",//iPad的ua，Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; zh-cn) AppleWebKit/531.21.10 (KHTML like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10
                "Android",//Android是否也转wap？Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; XT800 Build/TITA_M2_16.22.7) AppleWebKit/530.17 (KHTML like Gecko) Version/4.0 Mobile Safari/530.17
                "BlackBerry",//BlackBerry8310/2.7.0.106-4.5.0.182
                "UCWEB",//ucweb是否只给wap页面？ Nokia5800 XpressMusic/UCWEB7.5.0.66/50/999
                "ucweb",//小写的ucweb貌似是uc的代理服务器Mozilla/6.0 (compatible; MSIE 6.0;) Opera ucweb-squid
                "BREW",//很奇怪的ua，例如：REW-Applet/0x20068888 (BREW/3.1.5.20; DeviceId: 40105; Lang: zhcn) ucweb-squid
                "J2ME",//很奇怪的ua，只有J2ME四个字母
                "YULONG",//宇龙手机，YULONG-CoolpadN68/10.14 IPANEL/2.0 CTC/1.0
                "YuLong",//还是宇龙
                "COOLPAD",//宇龙酷派YL-COOLPADS100/08.10.S100 POLARIS/2.9 CTC/1.0
                "TIANYU",//天语手机TIANYU-KTOUCH/V209/MIDP2.0/CLDC1.1/Screen-240X320
                "TY-",//天语，TY-F6229/701116_6215_V0230 JUPITOR/2.2 CTC/1.0
                "K-Touch",//还是天语K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
                "Haier",//海尔手机，Haier-HG-M217_CMCC/3.0 Release/12.1.2007 Browser/WAP2.0
                "DOPOD",//多普达手机
                "Lenovo",// 联想手机，Lenovo-P650WG/S100 LMP/LML Release/2010.02.22 Profile/MIDP2.0 Configuration/CLDC1.1
                "LENOVO",// 联想手机，比如：LENOVO-P780/176A
                "HUAQIN",//华勤手机
                "AIGO-",//爱国者居然也出过手机，AIGO-800C/2.04 TMSS-BROWSER/1.0.0 CTC/1.0
                "CTC/1.0",//含义不明
                "CTC/2.0",//含义不明
                "CMCC",//移动定制手机，K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
                "DAXIAN",//大显手机DAXIAN X180 UP.Browser/6.2.3.2(GUI) MMP/2.0
                "MOT-",//摩托罗拉，MOT-MOTOROKRE6/1.0 LinuxOS/2.4.20 Release/8.4.2006 Browser/Opera8.00 Profile/MIDP2.0 Configuration/CLDC1.1 Software/R533_G_11.10.54R
                "SonyEricsson",// 索爱手机，SonyEricssonP990i/R100 Mozilla/4.0 (compatible; MSIE 6.0; Symbian OS; 405) Opera 8.65 [zh-CN]
                "GIONEE",//金立手机
                "HTC",//HTC手机
                "ZTE",//中兴手机，ZTE-A211/P109A2V1.0.0/WAP2.0 Profile
                "HUAWEI",//华为手机，
                "webOS",//palm手机，Mozilla/5.0 (webOS/1.4.5; U; zh-CN) AppleWebKit/532.2 (KHTML like Gecko) Version/1.0 Safari/532.2 Pre/1.0
                "GoBrowser",//3g GoBrowser.User-Agent=Nokia5230/GoBrowser/2.0.290 Safari
                "IEMobile",//Windows CE手机自带浏览器，
                "WAP2.0"//支持wap 2.0的
        };
        boolean pcFlag = false;
        boolean mobileFlag = false;
        String via = request.getHeader("Via");
        String userAgent = request.getHeader("user-agent");
        for (int i = 0; via!=null && !via.trim().equals("") && i < mobileGateWayHeaders.length; i++) {
            if(via.contains(mobileGateWayHeaders[i])){
                mobileFlag = true;
                break;
            }
        }
        for (int i = 0;!mobileFlag && userAgent!=null && !userAgent.trim().equals("") && i < mobileUserAgents.length; i++) {
            if(userAgent.contains(mobileUserAgents[i])){
                mobileFlag = true;
                break;
            }
        }
        for (int i = 0; userAgent!=null && !userAgent.trim().equals("") && i < pcHeaders.length; i++) {
            if(userAgent.contains(pcHeaders[i])){
                pcFlag = true;
                break;
            }
        }
        if(mobileFlag==true && pcFlag==false){
            return true;
        }else{
            return false;
        }
    }

	public static void main(String args[]){
    	System.out.println(CreateRandomStr(6));
    }
    
}
