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. Laravel 加载自定义的 helpers.php 函数

    Laravel 提供了很多 辅助函数,有时候我们也需要创建自己的辅助函数. 必须 把所有的『自定义辅助函数』存放于 bootstrap 文件夹中. 并在 bootstrap/app.php 文件的最顶 ...

  2. jquery和js中走的弯路

    1.$.each的错误用法 $.each的return xx 不能结束外层的函数,但return true/false可以 所以一般的: var result; $.each(json,functio ...

  3. vue webkit-box-orient: vertical打包线上不显示

    emmm……觉得不科学啊,写了几个vue的网站,限制超出行数省略号.结果发现放到线上,全都瓦特了.反复检查本地跑起来没错,代码没少,偏偏在线上的时候就是缺了vue -webkit-box-orient ...

  4. 2018.10.23 NOIP模拟 “新”的家园(缩图+dijksta/spfa)

    传送门 考试70分骗分写挂了=30分=全场最低. 哎今天230垫底了. 这题出的挺好. 对于非关键点直接缩点. 每次把要查的insertinsertinsert进缩好的图里面跑spfa/dijkstr ...

  5. 2018.07.06 POJ1698 Alice's Chance(最大流)

    Alice's Chance Time Limit: 1000MS Memory Limit: 10000K Description Alice, a charming girl, have been ...

  6. 关于EmitMapper,映射配置

    public static T Snapshoot<T>(this XtraForm form, T obj) { var config = new DefaultMapConfig(); ...

  7. HDU 2393 Higher Math (判断直角三角形)

    题意:给定三个边,判断是不是直角三角形. 析:水题,勾股定理... 代码如下: #include <iostream> #include <cstdio> #include & ...

  8. 通过wsdl生成client 的几种方式

    wsimport 位置 %JAVA_HOME%/bin/wsimport.exe 帮助 wsimport -help Usage: wsimport [options] <WSDL_URI> ...

  9. php一些方法说明

    var_dump():判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型.此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值.数组将递归展开值,通过缩进显 ...

  10. 最大连续子序列 -- hdu -- 1231

    http://acm.hdu.edu.cn/showproblem.php?pid=1231 最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Mem ...