智慧保安后台管理-外网
Administrator
2021-11-29 2a76be6f05cf13453b69609aa36d8548a5bae119
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package org.springblade.common.utils;
 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
 
/**
 * 身份证号码校验工具类
 * @author zhongrj
 * @since 2021-11-29
 */
public class IdCardNoUtil {
 
    /**
     * 身份证号码校验
     * @param idCardNo
     * @return
     */
    public static boolean checkIdCardNo(String idCardNo){
        //先校验长度
        if (idCardNo.length()!=18){
            return false;
        }
 
        //将末尾可能存在的x转成X
        idCardNo=idCardNo.toUpperCase();
 
        String regex="";
        //前6位地址码。后面仍需打表校验
        regex+="^[1-6]\\d{5}";
 
        //年份。后面仍需校验
        regex+="(18|19|20)\\d{2}";
        //月份。后面仍需校验
        regex+="((0[1-9])|(1[0-2]))";
        //日期。后面仍需校验
        regex+="(([0-2][1-9])|10|20|30|31)";
 
        //3位顺序码
        regex+="\\d{3}";
 
        //检验码。后面仍需验证
        regex+="[0-9X]";
 
        if(!idCardNo.matches(regex)){
            return false;
        }
 
        //第1,2位(省)打表进一步校验
        int[] d={11,12,13,14,15,
            21,22,23,31,32,33,34,35,36,37,
            41,42,43,
            44,45,46,
            50,51,52,53,53,
            61,62,63,64,65,
            83,81,82};
        boolean flag=false;
        int prov=Integer.parseInt(idCardNo.substring(0, 2));
        for(int i=0;i<d.length;i++) {
            if (d[i] == prov) {
                flag = true;
                break;
            }
        }
        if(!flag) {
            return false;
        }
        //生日校验:生日的时间不能比当前时间(指程序检测用户输入的身份证号码的时候)晚
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
 
        Date birthDate= null;
        try {
            birthDate = sdf.parse(idCardNo.substring(6, 14));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date curDate=new Date();
        if(birthDate.getTime()>curDate.getTime()) {
            return false;
        }
        //生日校验:每个月的天数不一样(有的月份没有31),还要注意闰年的二月
        int year=Integer.parseInt(idCardNo.substring(6, 10));
        int leap=((year%4==0 && year%100!=0) || year%400==0)?1:0;
        final int[] month={0,31,28+leap,31,30,31,30,31,31,30,31,30,31};
        int mon=Integer.parseInt(idCardNo.substring(10, 12));
        int day=Integer.parseInt(idCardNo.substring(12, 14));
        if(day>month[mon]){
            //System.out.println(day+" "+month[mon]+"\n");
            //System.out.println("---");
            return false;
        }
 
        //检验码
        if(idCardNo.charAt(17)!=getLastChar(idCardNo)) {
            return false;
        }
        return true;
    }
 
 
    /**
     * 根据身份证号码的前17位计算校验码
     * @param idNum
     * @return
     */
    public static char getLastChar(String idNum){
        final int[] w={0,7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
        //这就是为什么一开始将末尾可能存在的x转成X的原因
        final char[] ch={'1','0','X','9','8','7','6','5','4','3','2'};
        int res=0;
        for(int i=0;i<17;i++)
        {
            int t=idNum.charAt(i)-'0';
            res+=(t*w[i+1]);
        }
        return ch[res%11];
    }
}