智慧保安后台管理-外网
Administrator
2022-06-15 30701db6feddef40a7306b93f1571baaa5d0aeaa
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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;
    }
 
 
    /**
     *  根据身份证号判断用户性别
     * @param cardNo
     * @return
     */
    public static String getSex(String cardNo) {
        String sexStr = "0";
        if (cardNo.length() == 15) {
            sexStr = cardNo.substring(14, 15);
        } else if (cardNo.length() == 18) {
            sexStr = cardNo.substring(16,17);
        }
        int sexNo = Integer.parseInt(sexStr);
        return sexNo % 2 == 0 ? "女" : "男";
    }
 
    public static void main(String[] args) {
        System.out.println(getSex("530121198903119551"));
    }
 
 
    /**
     * 根据身份证号码的前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];
    }
}