RegUtil工具類 5.6.4

package com.jfai.kg.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
可以再maven pom.xml的<dependencies>依賴中中添加如下代碼,引入lombok工具包
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<version>1.16.20</version>
	</dependency>
 */
import lombok.extern.slf4j.Slf4j;

/**
 * @Package com.jfai.kg.util
 * @author wanglf
 * @version 5.6.4
 * @Description: RegUtil 字符串正則驗證類
 * @Time:2018年7月1日12:00:00
 * @Attention 
 * @Detail 
		 * 更新了字符串校驗傳入空值, 會報NullPointException的問題  2018年7月1日13:46:19
		 * 增強了空值校驗 2018年7月2日11:46:16
		 * 集成了 IDNoValidate 類驗證 2018年7月3日09:58:01
		 * 新增 ip:port Socket類型驗證和域名驗證 2018年7月3日11:11:46
		 * 新增英文校驗和經緯度校驗 2018年7月14日17:04:21
		 * 修復註釋問題,更新部分方法名 2018年7月18日13:40:43
		 * 新增護照號校驗功能並增強修正銀行卡卡號校驗,以及新增參數的null值判斷 2018年7月19日13:28:29
		 * 註釋更新 2018年7月25日17:28:49
		 * 新抽取參數空值判斷isNull()公共方法 2018年8月2日19:18:56
		 * 新增驗證是手機或平板請求的方法 2018年8月9日10:08:50
 * @remark
		 * 
 */
@Slf4j
public class RegUtil {
	/**
	 * 驗證是否是郵箱
	 *
	 * @param email
	 * @return true or false
	 */
	public static boolean isEmail(String email) {
		if (isNull(email)) {
			return false;
		}
		Pattern p = Pattern.compile("^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$");
		Matcher m = p.matcher(email);
		return m.matches();
	}

	/**
	 * 驗證是否是手機號碼
	 *
	 * @param mobileNo
	 * @return true or false true or false
	 * @Attention 
			 * 這裏使用的是寬鬆驗證,如果需要嚴格驗證需要使用reg_ex
			 * reg_ex已經包含新增的16開頭的號段
	 */
	public static boolean isMobileNO(String mobileNo) {
		if (isNull(mobileNo)) {
			return false;
		}
		String reg = "^[1][3-9]\\d{9}$";
		// String reg_ex =
		// "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
		return match(reg, mobileNo);
	}

	/**
	 * 驗證是否是電話號碼(包括手機號和固話)
	 *
	 * @param str  phone Number!
	 * @return true or false true or false
	 * @remark 新增16開頭的號段
	 */
	public static boolean isPhoneNo(String str) {
		if (isNull(str)) {
			return false;
		}
		return isMobileNO(str) || isFixPhone(str);
	}

	/**
	 * 驗證是否是護照號
	 *
	 * @param passportNO
	 * @return true or false
	 * @Description:
	 */
	public static boolean isPassport(String passportNO) {
		if (isNull(passportNO)) {
			return false;
		}
		String reg = "^1[45][0-9]{7}$|([P|p|S|s]\\d{7}$)|([S|s|G|g|E|e]\\d{8}$)|([Gg|Tt|Ss|Ll|Qq|Dd|Aa|Ff]\\d{8}$)|([H|h|M|m]\\d{8,10})$";
		return match(reg, passportNO);
	}

	/**
	 * 驗證是否是固話號碼
	 *
	 * @param fixPhoneNum 固話號
	 * @return true or false
	 */
	public static boolean isFixPhone(String fixPhoneNum) {
		if (isNull(fixPhoneNum)) {
			return false;
		}
		String reg = "(?:(\\(\\+?86\\))(0[0-9]{2,3}\\-?)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?)|" + "(?:(86-?)?(0[0-9]{2,3}\\-?)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?)";
		return match(reg, fixPhoneNum);
	}

	/**
	 * 校驗字符串是否是英文字母,不分大小寫
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isEnglish(String str) {
		if (isNull(str)) {
			return false;
		}
		Pattern p = Pattern.compile("^[A-Za-z]+$");
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * 驗證端口號
	 *
	 * @param port
	 * @return true or false
	 */
	public static boolean isPort(String port) {
		if (isNull(port)) {
			return false;
		}
		String reg = "^([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-5]{2}[0-3][0-5])$";
		return match(reg, port);
	}

	/**
	 * 驗證IPv4
	 *
	 * @param IPv4
	 * @return true or false
	 */
	public static boolean isIPv4(String IPv4) {
		if (isNull(IPv4)) {
			return false;
		}
		String reg = "\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";
		return match(reg, IPv4);
	}

	/**
	 * 驗證IPv6
	 *
	 * @param IPv6
	 * @return true or false
	 */
	public static boolean isIPv6(String IPv6) {
		if (isNull(IPv6)) {
			return false;
		}
		String reg = "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))";
		return match(reg, IPv6);
	}

	/**
	 * 驗證套接字   ip:port    Socket通常也稱作"套接字",用於描述IP地址和端口
	 *
	 * @param socket
	 * @return true or false
	 * @Description: 該函數的功能描述
	 */
	public static boolean isSocket(String socket) {
		if (isNull(socket)) {
			return false;
		}
		String reg = "((?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\\:(?:[0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-5]{2}[0-3][0-5]))";
		return match(reg, socket);
	}

	/**
	 * 驗證郵編
	 *
	 * @param postCode
	 * @return true or false
	 */
	public static boolean isPostCode(String postCode) {
		if (isNull(postCode)) {
			return false;
		}
		String reg = "[1-9]\\d{5}";
		return match(reg, postCode);
	}

	/**
	 * 驗證是否是用戶名
	 * 以字母開頭,4-20位大小寫數字或下劃線組成
	 *
	 * @param userName str
	 * @return true or false true or falsetrue 符合規定 false 不符合規定
	 */
	public static boolean checkUserName(String userName) {
		if (isNull(userName)) {
			return false;
		}
		Pattern p = Pattern.compile("^[a-zA-Z]+([a-zA-Z0-9]|[_]){2,20}$");
		Matcher m = p.matcher(userName);
		return m.matches();
	}

	/**
	 * 驗證是否是userid  1-19位的正整數   最大 :9223372036854775807  bigint(20)  java Long MAX_VALUE
	 *
	 * @param userId
	 * @return true or false true or false
	 */
	public static boolean isUserId(String userId) {
		if (isNull(userId)) {
			return false;
		}
		Pattern p = Pattern.compile("[1-9][0-9]{0,18}");
		Matcher m = p.matcher(userId);
		return m.matches();
	}

	/**
	 * 驗證密碼是否是6-16位
	 * 格式爲:6-16位,字母區分大小寫
	 *
	 * @param password
	 * @return true or false
	 */
	public static boolean isPassWord(String password) {
		if (isNull(password)) {
			return false;
		}
		// Pattern p = Pattern.compile("^[0-9a-zA-Z\\.\\_]{6,20}$");
		// Matcher m = p.matcher(password);
		// logger.info(m.matches()+"---");
		int len = password.length();
		boolean bol = true;
		if (len < 6 || len > 16) {
			bol = false;
		}
		return bol;
	}

	/**
	 * 驗證是否是手機驗證碼
	 * 4位或6位數字
	 *
	 * @param proving
	 * @return true or false
	 */
	public static boolean isCellPhoneProving(String proving) {
		if (isNull(proving)) {
			return false;
		}
		Pattern p = Pattern.compile("\\d{4}|\\d{6}");
		Matcher m = p.matcher(proving);
		return m.matches();
	}

	/**
	 * 驗證字符串是否是日期 ,現支持yyyy-MM-dd,yyyyMMdd或yyMMdd三種格式
	 *
	 * @param dateStr
	 * @return true or false
	 * @remark 經測試只有yyyy-MM-dd,yyyyMMdd和yyMMdd格式通過,yyyy-MM-dd HH:mm:ss格式不通過
	 * @result 
	 */
	public static boolean isDate(String dateStr) {
		if (isNull(dateStr)) {
			return false;
		}
		String reg = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$";
		Pattern pattern = Pattern.compile(reg);
		Matcher m = pattern.matcher(dateStr);
		if (m.matches()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @param str       日期字符串
	 * @param formatStr 日期格式化字符串
	 * @return true or false
	 * @Description: 驗證日期字符串合法性
	 */
	public static boolean validDateStr(String str, String formatStr) {
		if (isNull(str) || isNull(formatStr)) {
			return false;
		}

		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		try {
			// 設置lenient爲false. 否則SimpleDateFormat會比較寬鬆地驗證日期,比如2007/02/29會被接受,並轉換成2007/03/01
			format.setLenient(false);
			format.parse(str);
			return true;
		} catch (ParseException e) {
			// e.printStackTrace();
			// 如果throw java.text.ParseException或者NullPointerException,就說明格式不對
			return false;
		}
	}

	/**
	 * 驗證字符串是否是大於等於0的整數
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isNumber(String str) {
		if (isNull(str)) {
			return false;
		}
		Pattern p = Pattern.compile("^[0-9]+$");
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * 校驗數字,包括小數和負數
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isDigit(String str) {
		if (isNull(str)) {
			return false;
		}
		Pattern p = Pattern.compile("^-?[0-9]*.?[0-9]*$");
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * 驗證字符串是否是IMEI
	 *
	 * @param str
	 * @return true or false
	 * @remark 手機IMEI碼由15-17位數字組成,超出15位的爲軟件版本號,其主體由以下四個部分組成
	 * 1,前6位數(TAC,TYPE APPROVAL CODE)是"型號覈准號碼",一般代表機型。   
	 * 2,接着的2位數(FAC-Final Assembly Code)是"最後裝配號",一般代表產地。   
	 * 3,之後的6位數(SNR)是"串號",一般代表生產順序號。   
	 * 4,最後1位數(SP)爲檢驗碼
	 */
	public static boolean isIMEI(String str) {
		if (isNull(str) || !isNumber(str)) {
			return false;
		}

		if (str.length() == 15 || str.length() == 17) {
			String left = str.substring(0, 14);
			return (String.valueOf(str.charAt(14))).equals(getIMEIGeneCode(left));
		} else {
			if (str.length() == 16) {
				log.error("尚不知有16位的IMEI,記錄之..");
				log.error("It is not known that there are 16 IMEI , Registered..");
				log.error("IMEI:{}", str);
			}
			return false;
		}

		/*
		 * Pattern p = Pattern.compile("^[0-9]{15}$"); Matcher m = p.matcher(str);
		 * return m.matches();
		 */
	}

	// gencode 二維碼生成 正在翻譯 翻譯ing
	// gene code 基因密碼 遺傳密碼
	/**
	 * 依據傳入的14位數字生成IMEI的第15位校驗碼
	 * @param code IMEI的前14位數字
	 * @return IMEI的第15位合法校驗碼
	 * @Description: getIMEI15
	 */
	public static String getIMEIGeneCode(String code) {
		if (isNull(code)) {
			return "";
		}

		if (!isNumber(code) || code.length() != 14) {
			return "";
		}
		int total = 0, sum1 = 0, sum2 = 0;
		int temp = 0;
		char[] chs = code.toCharArray();
		for (int i = 0; i < chs.length; i++) {
			int num = chs[i] - '0'; // ascii to num
			// System.out.println(num);
			/* (1)將奇數位數字相加(從1開始計數) */
			if (i % 2 == 0) {
				sum1 = sum1 + num;
			} else {
				/* (2)將偶數位數字分別乘以2,分別計算個位數和十位數之和(從1開始計數) */
				temp = num * 2;
				if (temp < 10) {
					sum2 = sum2 + temp;
				} else {
					sum2 = sum2 + temp + 1 - 10;
				}
			}
		}
		total = sum1 + sum2;
		/* 如果得出的數個位是0則校驗位爲0,否則爲10減去個位數 */
		if (total % 10 == 0) {
			return "0";
		} else {
			return (10 - (total % 10)) + "";
		}
	}

	/**
	 * 驗證字符串是否是URL
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isUrl(String str) {
		if (isNull(str)) {
			return false;
		}
		String regex = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * 是否平板或手機訪問
	 * @param userAgent
	 * @return
	 * @version 1.0.0
	 * @Attention 注意驗證的是訪問中的USER-AGENT字段
	 * @Demo 
			 * String userAgent = request.getHeader("USER-AGENT");
			 * boolean isphoneVisit =RegUtil.isMobileVisit(userAgent);
	 */
	public static boolean isMobileVisit(String userAgent) {
		if (isNull(userAgent)) {
			return false;
		}
		String phoneReg = "\\bNokia|SAMSUNG|MIDP-2|CLDC1.1|SymbianOS|MAUI|UNTRUSTED/1.0" + "|Windows CE|iPhone|iPad|Android|BlackBerry|UCWEB|ucweb|BREW|J2ME|YULONG|YuLong|COOLPAD|TIANYU|TY-" + "|K-Touch|Haier|DOPOD|Lenovo|LENOVO|HUAQIN|AIGO-|CTC/1.0|CTC/2.0|CMCC|DAXIAN"
				+ "|MOT-|SonyEricsson|GIONEE|HTC|ZTE|HUAWEI|webOS|GoBrowser|IEMobile|WAP2.0\\b";
		String tableReg = "\\b(ipad|tablet|(Nexus 7)|up.browser" + "|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

		// 移動設備正則匹配: 手機端 平板
		Pattern phonePat = Pattern.compile(phoneReg, Pattern.CASE_INSENSITIVE);
		Pattern tablePat = Pattern.compile(tableReg, Pattern.CASE_INSENSITIVE);

		Matcher matcherPhone = phonePat.matcher(userAgent);
		Matcher matcherTable = tablePat.matcher(userAgent);
		if (matcherPhone.find() || matcherTable.find()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 驗證字符串是否是域名 
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isDomainName(String str) {
		if (isNull(str)) {
			return false;
		}
		// ^在[]裏面代表是非數字,所以它代表是非
		String regex = "(^[\\w][^//]*?\\.(?:com\\.cn|net\\.cn|org\\.cn|com|cn|net|org|biz|info|cc|tv)$)";
		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * 驗證身份證ID
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isIDNo(String str) {
		if (isNull(str)) {
			return false;
		}
		return isIDCard(str);
		/**
		 if (isNull(str)) { return false; }
		 String regex = "^(\\d{16}|\\d{18}|\\d{17}(X|x))$";
		 return match(regex, str);
		 */
	}

	/**
	 * 驗證是否是合法的月數
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isMonth(String str) {
		if (isNull(str)) {
			return false;
		}
		String regex = "^(0?[[1-9]|1[0-2])$";
		return match(regex, str);
	}

	/**
	 * 驗證是否是合法的天數
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isDay(String str) {
		if (isNull(str)) {
			return false;
		}
		String regex = "^((0?[1-9])|((1|2)[0-9])|30|31)$";
		return match(regex, str);
	}

	/**
	 * 驗證是否是大寫字符串
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isUpString(String str) {
		if (isNull(str)) {
			return false;
		}
		String regex = "^[A-Z]+$";
		return match(regex, str);
	}

	/**
	 * 驗證是否是小寫字符串
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isLowString(String str) {
		if (isNull(str)) {
			return false;
		}
		String regex = "^[a-z]+$";
		return match(regex, str);
	}

	/**
	 * 驗證是否是漢字字符串
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isChinese(String str) {
		if (isNull(str)) {
			return false;
		}
		String regex = "^[\u4e00-\u9fa5|\uf900-\ufa2d]+$";
		return match(regex, str);
	}

	/**
	 * 驗證是否是中國名字
	 *
	 * @param str
	 * @return true or false
	 */
	public static boolean isChineseName(String str) {
		if (str == null || str.length() == 0 || "".equals(str.trim()) || "NULL".equals(str.trim().toUpperCase())) {
			return false;
		}
		String regex = "^[\u4e00-\u9fa5|\uf900-\ufa2d|·]{2,20}$"; // · ==>Unicode 00B7
		return match(regex, str);
	}

	/**
	 * 驗證是否是符合規則的銀行卡號
	 *
	 * @param str
	 * @return true or false
	 * @describetion 包括信用卡(14,15,16,19位)和借記卡也就是儲蓄卡(16-19位)
	 * @remark 注意 工商銀行有15位卡號的信用卡和14位信用卡卡號
	 */
	public static boolean isBankCardNo(String str) {
		if (isNull(str)) {
			return false;
		}
		String reg = "^([1-9]{1})(\\d{13,18})$";
		return match(reg, str);
	}

	/**
	 * 驗證經度
	 *
	 * @param value 需要校驗的值 如:123.377586
	 * @return true or false
	 */
	public static boolean checkLongitude(String value) {
		if (isNull(value)) {
			return false;
		}
		Pattern p = Pattern.compile("^[\\-\\+]?(0?\\d{1,2}\\.\\d{1,5}|1[0-7]?\\d{1}\\.\\d{1,12}|180\\.0{1,12})$");
		Matcher m = p.matcher(value);
		return m.matches();
	}

	/**
	 * 驗證緯度
	 *
	 * @param value 需要校驗的值 如: 41.799303
	 * @return true or false
	 */
	public static boolean checkLatitude(String value) {
		if (isNull(value)) {
			return false;
		}
		Pattern p = Pattern.compile("^[\\-\\+]?([0-8]?\\d{1}\\.\\d{1,12}|90\\.0{1,12})$");
		Matcher m = p.matcher(value);
		return m.matches();
	}

	/**
	 * 判斷字符是否爲空或空白字符串,或各種null組成
	 */
	public static boolean isNull(String str) {
		return str == null || str.length() == 0 || "".equals(str.trim()) || "NULL".equals(str.trim().toUpperCase()) || "NULLNULL".equals(str.trim().toUpperCase()) || "NULLNULLNULL".equals(str.trim().toUpperCase());
	}

	/**
	 * 匹配驗證輔助方法
	 * @param regex
	 * @param str
	 * @return true or false
	 */
	public static boolean match(String regex, String str) {
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(str);
		return m.matches();
		// reg =\\< *[img][^\\\\>]*[src] *= *[\\"\\']{0,1}([^\\"\\'\\ >]*) 提取網頁中的圖片信息
		// reg=(<a\\s*(?!.*\\brel=)[^>]*)(href="https?:\\/\\/)((?!(?:(?:www\\.)?'.implode('|(?:www\\.)?',
		// $follow_list).'))[^"]+)"((?!.*\\brel=)[^>]*)(?:[^>]*)> 提取html頁面中的超鏈接
	}

	/**
	 * 驗證是否是符合官方規則的身份證號 注意:現使用的身份證號有不符合現行的官方身份證號規則的(說白了,就是登記的時候警察叔叔填錯了~~ 坑----)
	 * @param iDString
	 * @return true or false
	 */
	public static boolean isIDCard(String iDString) {
		String IDStr = iDString.toUpperCase(); // 這裏要注意身份證最後一位 小寫x和大寫X的問題
		String errorInfo = "";// 記錄錯誤信息
		boolean flag = true;
		String[] ValCodeArr = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
		String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" };
		String Ai = "";
		// ================ 判斷字符串是否爲空 ================
		if (IDStr == null || IDStr.length() == 0 || IDStr.trim().equals("") || IDStr.trim().toLowerCase().equals("null")) {
			errorInfo = "身份證號碼爲空或空白字符串或各種大小寫的null字符組成";
			flag = false;
			log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
			return false;
		}
		// =======================(end)========================
		// ================ 號碼的長度 15位或18位 ================
		if (IDStr.length() != 15 && IDStr.length() != 18) {
			errorInfo = "身份證號碼長度應該爲15位或18位。";
			flag = false;
			log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
			return false;
		}
		// =======================(end)========================
		// ================ 數字 除最後以爲都爲數字 ================
		if (IDStr.length() == 18) {
			Ai = IDStr.substring(0, 17);
		} else if (IDStr.length() == 15) {
			Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);
		}
		if (RegUtil.isNumber(Ai) == false) {
			errorInfo = "身份證15位號碼都應爲數字 ; 18位號碼除最後一位外,都應爲數字。";
			flag = false;
			log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
			return false;
		}
		// =======================(end)========================
		// ================ 出生年月是否有效 ================
		String strYear = Ai.substring(6, 10);// 年份
		String strMonth = Ai.substring(10, 12);// 月份
		String strDay = Ai.substring(12, 14);// 月份
		if (RegUtil.isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
			errorInfo = "身份證生日無效。";
			flag = false;
			log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
			return false;
		}
		GregorianCalendar gc = new GregorianCalendar();
		SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
		try {
			if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150 || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
				errorInfo = "身份證生日不在有效範圍。";
				flag = false;
				log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
				return false;
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (java.text.ParseException e) {
			e.printStackTrace();
		}
		if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
			errorInfo = "身份證月份無效";
			flag = false;
			log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
			return false;
		}
		if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
			errorInfo = "身份證日期無效";
			flag = false;
			log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
			return false;
		}
		// =====================(end)=====================
		// ================ 校驗地區碼是否有效 =================
		Map<String, String> h = GetAreaCode();
		if (h.get(Ai.substring(0, 2)) == null) {
			errorInfo = "身份證地區編碼錯誤。";
			flag = false;
			log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
			return false;
		}
		// ================================================
		// ================ 判斷最後一位的值 ================
		int TotalmulAiWi = 0;
		for (int i = 0; i < 17; i++) {
			TotalmulAiWi = TotalmulAiWi + Integer.parseInt(String.valueOf(Ai.charAt(i))) * Integer.parseInt(Wi[i]);
		}
		int modValue = TotalmulAiWi % 11;
		String strVerifyCode = ValCodeArr[modValue];
		Ai = Ai + strVerifyCode;
		if (IDStr.length() == 18) {
			if (Ai.equals(IDStr) == false) {
				errorInfo = "身份證最後一位校驗不合法,不是合法的身份證號碼,合法的身份證號應該爲:" + Ai;
				flag = false;
				log.error("IDStr:{},checkResult:{},errorInfo:{}", IDStr, flag, errorInfo);
				return false;
			}
		}
		// =====================(end)=====================
		log.info("IDStr:{},checkResult:{},Info:{}", IDStr, flag, "恭喜你校驗成功!");
		return flag;
	}

	/**
	 * 功能:獲取身份證號地區編碼
	 *
	 * @return HashMap 對象
	 */
	public static Map<String, String> GetAreaCode() {
		Map<String, String> hashtable = new HashMap<String, String>();
		hashtable.put("11", "北京");
		hashtable.put("12", "天津");
		hashtable.put("13", "河北");
		hashtable.put("14", "山西");
		hashtable.put("15", "內蒙古");
		hashtable.put("21", "遼寧");
		hashtable.put("22", "吉林");
		hashtable.put("23", "黑龍江");
		hashtable.put("31", "上海");
		hashtable.put("32", "江蘇");
		hashtable.put("33", "浙江");
		hashtable.put("34", "安徽");
		hashtable.put("35", "福建");
		hashtable.put("36", "江西");
		hashtable.put("37", "山東");
		hashtable.put("41", "河南");
		hashtable.put("42", "湖北");
		hashtable.put("43", "湖南");
		hashtable.put("44", "廣東");
		hashtable.put("45", "廣西");
		hashtable.put("46", "海南");
		hashtable.put("50", "重慶");
		hashtable.put("51", "四川");
		hashtable.put("52", "貴州");
		hashtable.put("53", "雲南");
		hashtable.put("54", "西藏");
		hashtable.put("61", "陝西");
		hashtable.put("62", "甘肅");
		hashtable.put("63", "青海");
		hashtable.put("64", "寧夏");
		hashtable.put("65", "新疆");
		hashtable.put("71", "臺灣");
		hashtable.put("81", "香港");
		hashtable.put("82", "澳門");
		hashtable.put("91", "國外");
		return hashtable;
	}

	public static void main(String[] args) {

		// System.out.println(isPhoneProving("33459"));
		// System.out.println("05711514256601570".length());
		// System.out.println(isIMEI("057115142566015"));
		// System.out.println(isBankCardNo("36091925818434"));
		// System.out.println(isEmail("[email protected]"));
		// System.out.println(isBankCardNo("622908211326127716"));

		// System.out.println(isFixPhone("02782665666"));
		// System.out.println(isFixPhone("06686330609"));

		// System.out.println(isPort("23355"));
		// System.out.println(isIPv4("10.3.0.222"));
		// System.out.println(isIPv4("000.000.000.000"));
		// System.out.println(isIPv4("0.0.0.0"));
		// System.out.println(isSocket("10.3.0.222:2181"));

		// System.out.println(isDomainName("wxapi.9fbank.com"));
		// System.out.println(isDomainName("scgyc.9fbank.com"));
		// System.out.println(isDomainName("www.baidu.com"));
		// System.out.println(isDomainName("https://www.baidu.com"));
		// System.out.println(isDomainName("http://www.baidu.com"));
		// System.out.println(isDomainName("/www.baidu.com"));
		// System.out.println(isDomainName("//www.baidu.com"));
		// System.out.println(isDomainName(":www.baidu.com"));
		// System.out.println(isDomainName("'www.baidu.com"));
		// System.out.println(isDomainName("100.114.89.69:9012"));
		// System.out.println(isDomainName(null));
		// System.out.println(isDomainName(""));

		// System.out.println(isDate("2016-10-06"));
		// System.out.println(isDate("2016-10-06 16:24:36"));
		// System.out.println(isDate("2016-10-06 16:24:36:8"));
		// System.out.println(isDate("2016-10-06 16:24:36:89"));
		// System.out.println(isDate("2016-10-06 16:24:36:102"));
		// System.out.println(isDate("20161006"));
		// System.out.println(isDate("20161006162436"));
		// System.out.println(isDate("180712"));

		// System.out.println(isDate("20120-10-06"));
		// System.out.println(isDate("2016-100-06"));
		// System.out.println(isDate("2016-10-81"));
		// System.out.println(isDate("100-10-01"));

		// String FixedPhone = "0571-8888880-111";
		// System.out.println(isFixPhone("010-89178263"));

		// System.out.println(isNumber(" "));
		// System.out.println(isChineseName("粑粑熱烈·木木麥提"));
		// System.out.println(RegUtil.isEmail("[email protected]"));
		// System.out.println(RegUtil.isMobileNO("18866666666"));
		// System.out.println(RegUtil.isUserName("a2_2ss號"));
		// System.out.println(RegUtil.isNumber("0.22222"));
		// System.out.println(RegUtil.isPhoneProving("222_22"));
		// System.out.println(RegUtil.isIMEI("11111111111111"));
		// String cardNo = StringUtil.getNum(16);
		// System.out.println(cardNo);
		// System.out.println(isCardNo(cardNo));
		// System.out.println(isChineseName("王·木木麥提"));
		// System.out.println(isIDCard("41041119921101559X"));
	}

}

// 其他符號中,至少有四個可能被混淆用於中文姓名的居中圓點:「∙」「•」「・」「●」,分別叫做「Bullet
// Operator」,「Bullet」,「Katakana Middle Dot」,「Black Circle」


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章