java验证身份证合理性

时间:2023-03-09 21:09:00
java验证身份证合理性

package com.tiantian.util;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

public class ValidateIdCardNoUtil {
private static Map<Integer, String> cityMap = new HashMap<Integer, String>();
static {
cityMap.put(11, "北京");
cityMap.put(12, "天津");
cityMap.put(13, "河北");
cityMap.put(14, "山西");
cityMap.put(15, "内蒙古");

cityMap.put(21, "辽宁");
cityMap.put(22, "吉林");
cityMap.put(23, "黑龙江");

cityMap.put(31, "上海");
cityMap.put(32, "江苏");
cityMap.put(33, "浙江");
cityMap.put(34, "安徽");
cityMap.put(35, "福建");
cityMap.put(36, "江西");
cityMap.put(37, "山东");

cityMap.put(41, "河南");
cityMap.put(42, "湖北");
cityMap.put(43, "湖南");
cityMap.put(44, "广东");
cityMap.put(45, "广西");
cityMap.put(46, "海南");

cityMap.put(50, "重庆");
cityMap.put(51, "四川");
cityMap.put(52, "贵州");
cityMap.put(53, "云南");
cityMap.put(54, "*");

cityMap.put(61, "陕西");
cityMap.put(62, "甘肃");
cityMap.put(63, "青海");
cityMap.put(64, "宁夏");
cityMap.put(65, "*");

cityMap.put(71, "*");
cityMap.put(81, "香港");
cityMap.put(82, "澳门");
cityMap.put(91, "国外");
}

public static boolean validatorIdCardNo(String idCardNo) {
// 非空校验
if (StringUtils.isBlank(idCardNo)) {
return false;
}
// 校验长度,类型
if (!isCardNo(idCardNo)) {
return false;
}
// 检查省份
if (!checkProvince(idCardNo)) {
return false;
}
// 校验生日
if (!checkBirthday(idCardNo)) {
return false;
}
// 检验位的检测
if (!checkParity(idCardNo)) {
return false;
}
return true;
}

private static boolean match(String regex, String str) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.matches();
}

public static int[] birthdayAboutValue(String regex, String idCardNo) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(idCardNo);
int[] tmp = new int[3];

while (m.find()) {
int len = tmp.length;
int index = 5;
while (len > 0) {
tmp[--len] = Integer.parseInt(m.group(index = index - 1));
}
}
return tmp;
}

// 检查号码是否符合规范,包括长度,类型
private static boolean isCardNo(String idCardNo) {
String regex = "(^\\d{15}$)|(^\\d{17}(\\d|X)$)";
return match(regex, idCardNo);
}

// 取身份证前两位,校验省份
private static boolean checkProvince(String idCardNo) {
// 前面先严重了长度,在此不进行非空校验
Integer province = Integer.parseInt(idCardNo.substring(0, 2));
if (StringUtils.isNotBlank(cityMap.get(province))) {
return true;
}
return false;
}

// 检查生日是否正确
private static boolean checkBirthday(String idCardNo) {
int len = idCardNo.length();
int[] value = null;
// 身份证15位时,次序为省(3位)市(3位)年(2位)月(2位)日(2位)校验位(3位),皆为数字
if (len == 15) {
String re_fifteen = "^(\\d{6})(\\d{2})(\\d{2})(\\d{2})(\\d{3})$";
value = birthdayAboutValue(re_fifteen, idCardNo);
int year = value[0];
int month = value[1];
int day = value[2];
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
return verifyBirthday(year, month, day, calendar);
}
if (len == 18) {
String re_fifteen = "^(\\d{6})(\\d{4})(\\d{2})(\\d{2})(\\d{3})([0-9]|X)$";
value = birthdayAboutValue(re_fifteen, idCardNo);
int year = value[0];
int month = value[1];
int day = value[2];
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
return verifyBirthday(year, month, day, calendar);
}
return false;
}

// 校验日期
private static boolean verifyBirthday(int year, int month, int day,
Calendar birthday) {
Calendar now = Calendar.getInstance();
int nowyear = now.get(Calendar.YEAR);
// 年月日是否合理
if (birthday.get(Calendar.YEAR) == year
&& (birthday.get(Calendar.MONTH)) == month
&& birthday.get(Calendar.DATE) == day) {
// 判断年份的范围(3岁到100岁之间)
int time = nowyear - year;
if (time >= 3 && time <= 100) {
return true;
}
}
return false;
}

// 校验位的检测
private static boolean checkParity(String idCardNo) {
String card = IdCardUtil.getPrecise18BitIdCardNo(idCardNo);
int len = card.length();
if (len == 18) {
int[] arrInt = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10,
5, 8, 4, 2 };
char[] arrChar = new char[] { '1', '0', 'X', '9', '8', '7', '6',
'5', '4', '3', '2' };
int cardTemp = 0, i;
char valnum;
for (i = 0; i < 17; i++) {
cardTemp += Integer.parseInt(card.substring(i, i + 1))
* arrInt[i];
}
valnum = arrChar[cardTemp % 11];
if (Character.toString(valnum).equals(card.substring(17, 18))) {
return true;
}
return false;
}
return false;
}

public static void main(String[] args) {
System.out.println(validatorIdCardNo("45032619840627183X"));
}
}