|
@@ -0,0 +1,82 @@
|
|
|
|
|
+package com.crm.manager.util;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 18位身份证工具类(国标GB 11643-1999)
|
|
|
|
|
+ * 功能:校验身份证合法性、计算第18位校验码、15位转18位
|
|
|
|
|
+ */
|
|
|
|
|
+public class IdCardUtil {
|
|
|
|
|
+
|
|
|
|
|
+ // 17位加权因子
|
|
|
|
|
+ private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
|
|
|
|
|
+ // 校验码对照表(余数0-11对应)
|
|
|
|
|
+ private static final char[] CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 校验18位身份证是否合法
|
|
|
|
|
+ * @param idCard 18位身份证号码
|
|
|
|
|
+ * @return true=合法,false=非法
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean isValid18IdCard(String idCard) {
|
|
|
|
|
+ // 基础校验:长度必须18位
|
|
|
|
|
+ if (idCard == null || idCard.length() != 18) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 前17位必须是数字
|
|
|
|
|
+ String front17 = idCard.substring(0, 17);
|
|
|
|
|
+ if (!front17.matches("\\d+")) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算校验码
|
|
|
|
|
+ char calcCode = getCheckCode(front17);
|
|
|
|
|
+ // 获取身份证最后一位
|
|
|
|
|
+ char lastCode = idCard.charAt(17);
|
|
|
|
|
+
|
|
|
|
|
+ // 不区分大小写校验X
|
|
|
|
|
+ return Character.toUpperCase(calcCode) == Character.toUpperCase(lastCode);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算18位身份证的第18位校验码
|
|
|
|
|
+ * @param front17 身份证前17位
|
|
|
|
|
+ * @return 校验码(0-9、X)
|
|
|
|
|
+ */
|
|
|
|
|
+ public static char getCheckCode(String front17) {
|
|
|
|
|
+ int sum = 0;
|
|
|
|
|
+ for (int i = 0; i < 17; i++) {
|
|
|
|
|
+ int num = front17.charAt(i) - '0';
|
|
|
|
|
+ sum += num * WEIGHT[i];
|
|
|
|
|
+ }
|
|
|
|
|
+ // 取余
|
|
|
|
|
+ int remainder = sum % 11;
|
|
|
|
|
+ return CHECK_CODE[remainder];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 15位身份证升级为18位
|
|
|
|
|
+ * @param idCard15 15位身份证
|
|
|
|
|
+ * @return 18位身份证
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String convert15To18(String idCard15) {
|
|
|
|
|
+ if (idCard15 == null || idCard15.length() != 15 || !idCard15.matches("\\d+")) {
|
|
|
|
|
+ throw new IllegalArgumentException("非法15位身份证");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 15位=6位地址+6位生日(YYMMDD)+3位顺序码
|
|
|
|
|
+ // 18位=6位地址+8位生日(YYYYMMDD)+3位顺序码+1位校验码
|
|
|
|
|
+ String front17 = idCard15.substring(0, 6) + "19" + idCard15.substring(6);
|
|
|
|
|
+ char checkCode = getCheckCode(front17);
|
|
|
|
|
+ return front17 + checkCode;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 测试
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
|
+ // 测试1:合法身份证(可替换成真实身份证测试)
|
|
|
|
|
+ String id18 = "110101200606049510";
|
|
|
|
|
+ System.out.println("18位身份证校验结果:" + isValid18IdCard(id18)); // true
|
|
|
|
|
+
|
|
|
|
|
+// // 测试2:15位转18位
|
|
|
|
|
+// String id15 = "110101900307451";
|
|
|
|
|
+// System.out.println("15位转18位:" + convert15To18(id15)); // 11010119900307451X
|
|
|
|
|
+ }
|
|
|
|
|
+}
|