fhx
2024-09-29 e0ef9fe0ded50ac2c9e40c8616c99007048521c4
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package com.hx.util;
 
import org.apache.commons.lang.StringUtils;
 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
 
/**
 * 身份证号码逻辑校验-用于上报医疗数据
 * 该方法无法保证校验的身份证一定是真实存在的
 * */
public class IDCardUtil {
 
    public static Boolean check(String idCardNo){
        if (StringUtils.isEmpty(idCardNo)){
            return false;
        }
        //将其转成大写有的身份证最后一位是字母
        String idCard=idCardNo.toUpperCase();
        //15位身份证转成18位
        if (idCardNo.length() == 15) {
            if (!(idCardNo.matches("[0-9]{17}[0-9|x]|[0-9]{15}"))) {
                return false;
            }
            //15位转换为18位
            String s2 = idCardNo.substring(0, 6);
            String s3 = idCardNo.substring(6, 15);
            String changed = s2.concat("19").concat(s3);
            idCard = changed.toUpperCase();
        }
        //获取身份证最后一位进行验证
        String lastStr = idCard.substring(idCard.length() - 1);
        //获取身份证前17位
        String firstStr = idCard.substring(0,17);
        //验证身份证前17位是否为数字
        boolean isDigits = Pattern.matches("^\\d{17}", firstStr);
        if(!isDigits){
            return false;
        }
        //全局变量
        if(idCardMap.isEmpty()){
            for(int i=0;i<=10;i++){
                idCardMap.put(i,idCardCheck[i]);
            }
        }
        //是否合理
        boolean check=false;
 
        char[] idCardCharNumber = idCard.toCharArray();
        Integer resultSum = 0;
        for (int i = 0; i < idCardCharNumber.length - 1; i++) {
            resultSum += Character.getNumericValue(idCardCharNumber[i]) * idCardWeight[i];
        }
        //将相加的前17位数字依次乘以对应的权重因子相加,相加的结果除以11,得到余数
        Integer lastResult = resultSum % 11;
        //根据余数,对应一个指定的校验码。最终得到的校验码就是身份证号码的最后一位数字。
        // 通过这个校验码,可以验证前面17位数字是否正确,从而提高身份证号码的准确性
        if (idCardMap.get(lastResult) != null) {
            check = idCardMap.get(lastResult).equals(lastStr);
        }
        return check;
    }
 
 
 
    /**身份证前17位数字依次乘以对应的权重因子*/
    public static final Integer[] idCardWeight= {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    /**身份证最后一位对应的校验码*/
    public static final String[] idCardCheck= {"1","0","X","9","8","7","6","5","4","3","2"};
    /**星座数组*/
    public static final String[] CONSTELLATION_ARR = { "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "魔羯座" };
    /**星座对应的边缘日期*/
    public static final int[] CONSTELLATION_EDGE_DAY = {20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22};
    /**生肖*/
    public static final String[] ZODIAC_ARR = { "猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊" };
    /**组装根据余数,对应一个指定的校验码*/
    private static Map<Integer,String> idCardMap=new HashMap<>();
 
    /**根据日期获取星座*/
    private static String getConstellation(Date date) {
        if (date == null) {
            return "";
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int month = cal.get(Calendar.MONTH);
        int day = cal.get(Calendar.DAY_OF_MONTH);
        if (day < CONSTELLATION_EDGE_DAY[month]) {
            month = month - 1;
        }
        if (month >= 0) {
            return CONSTELLATION_ARR[month];
        }
        // default to return 魔羯
        return CONSTELLATION_ARR[11];
    }
 
    /**根据身份证号判断用户星座*/
    private static String getConstellation(String cardNo) {
        // 获取出生日期
        String birthday = cardNo.substring(6, 14);
        Date birthdate = null;
        try {
            birthdate = new SimpleDateFormat("yyyyMMdd").parse(birthday);
            return getConstellation(birthdate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**根据日期获取生肖*/
    private static String getZodica(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return ZODIAC_ARR[cal.get(Calendar.YEAR) % 12];
    }
 
    /**根据身份证号判断用户生肖*/
    private static String getZodica(String cardNo) {
        // 获取出生日期
        String birthday = cardNo.substring(6, 14);
        Date birthdate = null;
        try {
            birthdate = new SimpleDateFormat("yyyyMMdd").parse(birthday);
            return getZodica(birthdate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**15位转18位身份证号*/
    private static String get18Ic(String identityCard) {
        String retId = "";
        String id17 = "";
        int sum = 0;
        int y = 0;
        // 定义数组存放加权因子(weight factor)
        int[] wf = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
        // 定义数组存放校验码(check code)
        String[] cc = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
        if (identityCard.length() != 15) {
            return identityCard;
        }
        // 加上两位年19
        id17 = identityCard.substring(0, 6) + "19" + identityCard.substring(6);
        // 十七位数字本体码加权求和
        for (int i = 0; i < 17; i++) {
            sum = sum + Integer.valueOf(id17.substring(i, i + 1)) * wf[i];
        }
        // 计算模
        y = sum % 11;
        // 通过模得到对应的校验码 cc[y]
        retId = id17 + cc[y];
        return retId;
    }
}