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"));
}
}

java验证身份证合理性的更多相关文章

  1. JAVA验证身份证号码是否合法

    package com.chauvet.utils; import java.text.ParseException; import java.text.SimpleDateFormat; impor ...

  2. Java验证身份证是否合法

    import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; im ...

  3. JAVA验证身份证号码是否正确

    package com.IdCard; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.D ...

  4. JAVA验证身份证格式及合法性

    旅游电子商务中,预订酒店或订购门票时会以身份证作为消费凭证,为了防止客户误填身份证带来不必要麻烦,需要验证码格式及合法性,代码如下: /** * 判断身份证格式 * * @param idNum * ...

  5. java验证身份证号码是否有效源代码 wn25的头像 wn25 23 2015-01-04 20:09 6 基本信息 Java × 1 浏览

    原文:http://www.open-open.com/code/view/1420373343171 1.描述 用java语言判断身份证号码是否有效,地区码.出身年月.校验码等验证算法 2.源代码 ...

  6. java验证身份证号码是否有效源代码

    原文:http://www.open-open.com/code/view/1420373343171 1.描述 用java语言判断身份证号码是否有效,地区码.出身年月.校验码等验证算法 2.源代码 ...

  7. java 验证身份证号

  8. JAVA代码验证身份证信息

    java验证身份证信息代码 转自:http://www.blogjava.net/xylz/archive/2011/01/05/342330.html import java.util.Calend ...

  9. JAVA通过身份证号码获取出生日期、年龄、性别

    JAVA验证身份证号码是否正确:https://www.cnblogs.com/pxblog/p/12038278.html /** * 通过身份证号码获取出生日期(birthday).年龄(age) ...

随机推荐

  1. dumpbin 查看dll中的导出函数

    C:\Program Files (x86)\Microsoft Visual Studio 14.0>dumpbin -exports E:\20171110\Release\aa.dll h ...

  2. c#递归实现螺旋数组

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  3. Spring.NET学习笔记7——依赖对象的注入(基础篇) Level 200

    1.person类 public class Person    {        public string Name { get; set; }        public int Age { g ...

  4. Android 编译参数 LOCAL_MODULE_TAGS

    此参数会影响到库生成后的存放位置,影响生成位置的应该是相关平台下的变量PRODUCT_PACKAGES http://blog.csdn.net/evilcode/article/details/64 ...

  5. 2018.09.25 bzoj3572: [Hnoi2014]世界树(虚树+树形dp)

    传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然 ...

  6. 2018.07.04 BZOJ 2618 Cqoi2006凸多边形(半平面交)

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec Memory Limit: 128 MB Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n ...

  7. 2018.08.18 NOIP模拟 travel(贪心)

    Travel 题目背景 SOURCE:NOIP2015-SHY4 题目描述 小 A 要进行一次旅行.这回他要在序号为 1 到 n 的 n 个城市之间旅行.这 n 个城市之间共有 m 条连接两个城市的单 ...

  8. Django(3)

    https://www.cnblogs.com/yuanchenqi/articles/7429279.html

  9. 基于zookeeper的主备切换方法

    继承CZookeeperHelper即可快速实现主备切换: https://github.com/eyjian/libmooon/blob/master/include/mooon/net/zooke ...

  10. TensorFlow入门案例

    入门小案例,分别是回归模型建立和mnist数据集的模型建立 1.回归案例: import tensorflow as tf import numpy as np from tensorflow.exa ...