fhx
2024-09-29 e0ef9fe0ded50ac2c9e40c8616c99007048521c4
提交 | 用户 | age
225ca6 1 package com.hx.util;
F 2
3 import org.apache.commons.lang.StringUtils;
4
5 import java.text.ParseException;
6 import java.text.SimpleDateFormat;
7 import java.util.Calendar;
8 import java.util.Date;
9 import java.util.HashMap;
10 import java.util.Map;
11 import java.util.regex.Pattern;
12
13 /**
14  * 身份证号码逻辑校验-用于上报医疗数据
15  * 该方法无法保证校验的身份证一定是真实存在的
16  * */
17 public class IDCardUtil {
18
19     public static Boolean check(String idCardNo){
20         if (StringUtils.isEmpty(idCardNo)){
21             return false;
22         }
23         //将其转成大写有的身份证最后一位是字母
24         String idCard=idCardNo.toUpperCase();
25         //15位身份证转成18位
26         if (idCardNo.length() == 15) {
27             if (!(idCardNo.matches("[0-9]{17}[0-9|x]|[0-9]{15}"))) {
28                 return false;
29             }
30             //15位转换为18位
31             String s2 = idCardNo.substring(0, 6);
32             String s3 = idCardNo.substring(6, 15);
33             String changed = s2.concat("19").concat(s3);
34             idCard = changed.toUpperCase();
35         }
36         //获取身份证最后一位进行验证
37         String lastStr = idCard.substring(idCard.length() - 1);
38         //获取身份证前17位
39         String firstStr = idCard.substring(0,17);
40         //验证身份证前17位是否为数字
41         boolean isDigits = Pattern.matches("^\\d{17}", firstStr);
42         if(!isDigits){
43             return false;
44         }
45         //全局变量
46         if(idCardMap.isEmpty()){
47             for(int i=0;i<=10;i++){
48                 idCardMap.put(i,idCardCheck[i]);
49             }
50         }
51         //是否合理
52         boolean check=false;
53
54         char[] idCardCharNumber = idCard.toCharArray();
55         Integer resultSum = 0;
56         for (int i = 0; i < idCardCharNumber.length - 1; i++) {
57             resultSum += Character.getNumericValue(idCardCharNumber[i]) * idCardWeight[i];
58         }
59         //将相加的前17位数字依次乘以对应的权重因子相加,相加的结果除以11,得到余数
60         Integer lastResult = resultSum % 11;
61         //根据余数,对应一个指定的校验码。最终得到的校验码就是身份证号码的最后一位数字。
62         // 通过这个校验码,可以验证前面17位数字是否正确,从而提高身份证号码的准确性
63         if (idCardMap.get(lastResult) != null) {
64             check = idCardMap.get(lastResult).equals(lastStr);
65         }
66         return check;
67     }
68
69
70
71     /**身份证前17位数字依次乘以对应的权重因子*/
72     public static final Integer[] idCardWeight= {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
73     /**身份证最后一位对应的校验码*/
74     public static final String[] idCardCheck= {"1","0","X","9","8","7","6","5","4","3","2"};
75     /**星座数组*/
76     public static final String[] CONSTELLATION_ARR = { "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "魔羯座" };
77     /**星座对应的边缘日期*/
78     public static final int[] CONSTELLATION_EDGE_DAY = {20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22};
79     /**生肖*/
80     public static final String[] ZODIAC_ARR = { "猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊" };
81     /**组装根据余数,对应一个指定的校验码*/
82     private static Map<Integer,String> idCardMap=new HashMap<>();
83
84     /**根据日期获取星座*/
85     private static String getConstellation(Date date) {
86         if (date == null) {
87             return "";
88         }
89         Calendar cal = Calendar.getInstance();
90         cal.setTime(date);
91         int month = cal.get(Calendar.MONTH);
92         int day = cal.get(Calendar.DAY_OF_MONTH);
93         if (day < CONSTELLATION_EDGE_DAY[month]) {
94             month = month - 1;
95         }
96         if (month >= 0) {
97             return CONSTELLATION_ARR[month];
98         }
99         // default to return 魔羯
100         return CONSTELLATION_ARR[11];
101     }
102
103     /**根据身份证号判断用户星座*/
104     private static String getConstellation(String cardNo) {
105         // 获取出生日期
106         String birthday = cardNo.substring(6, 14);
107         Date birthdate = null;
108         try {
109             birthdate = new SimpleDateFormat("yyyyMMdd").parse(birthday);
110             return getConstellation(birthdate);
111         } catch (ParseException e) {
112             e.printStackTrace();
113         }
114         return null;
115     }
116
117     /**根据日期获取生肖*/
118     private static String getZodica(Date date) {
119         Calendar cal = Calendar.getInstance();
120         cal.setTime(date);
121         return ZODIAC_ARR[cal.get(Calendar.YEAR) % 12];
122     }
123
124     /**根据身份证号判断用户生肖*/
125     private static String getZodica(String cardNo) {
126         // 获取出生日期
127         String birthday = cardNo.substring(6, 14);
128         Date birthdate = null;
129         try {
130             birthdate = new SimpleDateFormat("yyyyMMdd").parse(birthday);
131             return getZodica(birthdate);
132         } catch (ParseException e) {
133             e.printStackTrace();
134         }
135         return null;
136     }
137
138     /**15位转18位身份证号*/
139     private static String get18Ic(String identityCard) {
140         String retId = "";
141         String id17 = "";
142         int sum = 0;
143         int y = 0;
144         // 定义数组存放加权因子(weight factor)
145         int[] wf = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
146         // 定义数组存放校验码(check code)
147         String[] cc = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
148         if (identityCard.length() != 15) {
149             return identityCard;
150         }
151         // 加上两位年19
152         id17 = identityCard.substring(0, 6) + "19" + identityCard.substring(6);
153         // 十七位数字本体码加权求和
154         for (int i = 0; i < 17; i++) {
155             sum = sum + Integer.valueOf(id17.substring(i, i + 1)) * wf[i];
156         }
157         // 计算模
158         y = sum % 11;
159         // 通过模得到对应的校验码 cc[y]
160         retId = id17 + cc[y];
161         return retId;
162     }
163 }