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. Crash以及报错总结

    CoreData: Cannot load NSManagedObjectModel.nil is an illegal URL parameter 这是因为在工程中CoreData的命名和AppDe ...

  2. 2018.10.23 hdu4745Two Rabbits(区间dp)

    传送门 区间dp经典题目. 首先断环为链. 然后题目相当于就是在找最大的回文子序列. 注意两个位置重合的时候相当于范围是n,不重合时范围是n-1. 代码: #include<bits/stdc+ ...

  3. 2018.07.23 hdu5828 Rikka with Sequence(线段树)

    传送门 这道题维护区间加,区间开根,区间求和. 线段树常规操作. 首先回忆两道简单得多的线段树. 第一个:区间覆盖,区间加,区间求和. 第二个:区间开根,区间求和. 这两个是名副其实的常规操作. 但这 ...

  4. maven随笔

    1.在我们项目顶层的POM文件中,我们会看到dependencyManagement元素.通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号.Maven会沿着父子层次向上走, ...

  5. java程序设计基本概念 jvm

    JVM (1)对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中.对于equals相等的字符串 ...

  6. mysql操作说明,插入时外键约束,快速删除

    快速删除: CMD命令 SET FOREIGN_KEY_CHECKS=0;去除外键约束 truncate table 表名;

  7. Android draw Rect 坐标图示

    前两天在博客发了在例子 android Canvas类介绍 http://byandby.javaeye.com/blog/825330 建议大家 点进去 看一看 不然下边没办法 继续啊. 我还是把这 ...

  8. 用Socket开发的一枚小型实时通信App

    Socket 英文原意是插座. 在网络世界里, 当一台主机温柔而体贴的同时提供多个服务时, 每个服务被绑定在一个端口上, 而每个端口就好像一个小插座. 用户们连接对应的插座去获取相应的服务. 在Nod ...

  9. (网络流) Sabotage -- UVA -- 10480

    链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82835#problem/J 代码: #include<cstdio> ...

  10. hdu 5003 模拟水题

    http://acm.hdu.edu.cn/showproblem.php?pid=5003 记得排序后输出 #include <cstdio> #include <cstring& ...