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. "UX"将会是下一个Buzzword?

    “用户体验非常重要”.“没有用户体验就没有产品”.“UX就是一切”.不知道从何时开始,用户体验(UX) 这个名词已经变得如此多见了,但是人们真正的认识.认清了什么是用户体验了吗?设计师们常挂在嘴边的用 ...

  2. 二进制搭建kubernetes多master集群【四、配置k8s node】

    上一篇我们部署了kubernetes的master集群,参考:二进制搭建kubernetes多master集群[三.配置k8s master及高可用] 本文在以下主机上操作部署k8s node k8s ...

  3. 2018.09.17 atcoder Tak and Hotels(贪心+分块)

    传送门 一道有意思的题. 一开始想错了,以为一直lowerlowerlower_boundboundbound就可以解决询问,结果交上去TLE了之后才发现时间复杂度是错的. 但是贪心思想一定是对的,每 ...

  4. 2018.07.31 bzoj4569: [Scoi2016]萌萌哒(并查集+倍增)

    传送门 对于每个限制,使用倍增的二进制拆分思想,用并查集数组fa[i][j]" role="presentation" style="position: rel ...

  5. 实现字符串函数,strlen(),strcpy(),strcmp(),strcat()

    实现字符串函数,strlen(),strcpy(),strcmp(),strcat() #include<stdio.h> #include<stdlib.h> int my_ ...

  6. fortran write格式

    advance="no",就是输出不换行. write(*,"(f10.1)",advance="no")A 格式化输出的控制字符非常的丰富 ...

  7. Win7下U盘安装CentOS-7-x86_64-DVD-1503-01

    转载自:http://blog.sina.com.cn/s/blog_842d5c8a0102vr12.html 昨天在Win7下装CentOS7,本以为之前装CentOS6.5很熟练了,结合网上的帖 ...

  8. spring + rs + RocketMQ 【精】

    cxf-rs-rocketmq 项目地址:见git │ pom.xml │ └─src ├─main │ ├─java │ │ └─cn │ │ └─zno │ │ ├─pojo │ │ │ Rece ...

  9. obj-c的优缺点

    优点: 1) Cateogies : 类别 2) Posing : 扮演 3) 动态识别 : 编译时与运行时动态识别类型 4) 指标计算 : 指针计算 指针的 +- * / 5) 弹性信息传递 : 某 ...

  10. vim 配置半透明

    转载两个博客 链接一 链接二