我们的身份证号码包含很多的信息,下面的代码提供了身份证的解析功能,具体看注释吧,已经写全了
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* @author Rob Sivan
* @date 2022/9/19 20:30
* @describe 身份证解析工具类
*/
public class IDCardUtil {
public static void main(String[] args) {
//预获取身份证号码
System.out.println("请输入身份证号码:");
String SId = new Scanner(System.in).nextLine();
if (SId.length() == 15) {
SId = SIdConversion(SId);
}
if (SId.length() != 18) {
System.out.println("请输入有效的身份证号码!");
} else if (IDVerification(SId)) {
// 前六位表示地址码,精确到县
char[] areaCode = new char[6];
for (int i = 0; i < 6; i++) {
areaCode[i] = SId.charAt(i);
}
String area = new String(areaCode);
// 从身份证中获取出生年月日并转换为String
char[] birthDate = new char[8];
for (int i = 0; i < 8; i++) {
birthDate[i] = SId.charAt(i + 6);
}
//获取当前日期并转换为字符串
Date date = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
String nowDate = df.format(date);
//根据二者转换出年龄
int age = (Integer.parseInt(nowDate) - Integer.parseInt(String.valueOf(birthDate))) / 10000;
StringBuilder sb = new StringBuilder(String.valueOf(birthDate));
sb.insert(4, "-");
sb.insert(7, "-");
String birth = sb.toString();
// 得到17位性别码
String gender = SId.charAt(16) % 2 == 1 ? "男" : "女";
// 执行输出方法
printInfo(area, birth, gender, age);
}
}
// 15位身份证转18位方法
public static String SIdConversionE(String SId) { // 解析版
String sid;
// 前六位表示地址码,精确到县
char[] areaCode = new char[8];
for (int i = 0; i < 6; i++) {
areaCode[i] = SId.charAt(i);
}
String area = new String(areaCode);
// 第七到十二位为出生年月日,较18位身份证少了年的前两位
char[] birthDate = new char[8];
birthDate[0] = '1';
birthDate[1] = '9';
for (int i = 2; i < 8; i++) {
birthDate[i] = SId.charAt(i + 4);
}
String birth = new String(birthDate);
// 第十三到十四位
char[] otherNum = new char[2];
for (int i = 0; i < 2; i++) {
otherNum[i] = SId.charAt(i + 12);
}
String other = new String(otherNum);
// 第十五位性别
String gander = SId.substring(14);
// 通过最后三位得到此时的17位身份证
String SIdTemp = area + birth + other + gander;
// 将此时15+2=17位的身份证与对应加权位数字相乘并相加
final int[] WEIGHTING_FACTOR = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; // 加权因子
int sum = 0;
for (int i = 0; i < 18; i++) {
int a = SIdTemp.charAt(i);
int b = WEIGHTING_FACTOR[i];
sum = sum + (a * b);
}
// 将和对11取模得到最后一位校验码
final String[] CHECK_CODE = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; // 校验码
String check = CHECK_CODE[((sum / 11) - 1)];
// 17位身份证加上最后一位校验码得到18位身份证
sid = SIdTemp + check;
return sid;
}
public static String SIdConversion(String SId) {
StringBuilder sb = new StringBuilder(SId);
sb.insert(6, "19");
String s = sb.toString();
System.out.println(s);
final int[] WEIGHTING_FACTOR = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; // 加权因子
int sum = 0;
for (int i = 0; i < 17; i++) {
int a = s.charAt(i) - 48;
int b = WEIGHTING_FACTOR[i];
sum += a * b;
}
System.out.println(sum);
int checkNum = sum % 11;
String[] CHECK_CODE = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; // 校验码
return s + CHECK_CODE[checkNum];
}
// 验证身份证是否正确
public static boolean IDVerification(String SId) {
String check = SId.substring(17);
final int[] WEIGHTING_FACTOR = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; // 加权因子
int sum = 0;
for (int i = 0; i < 17; i++) {
int a = SId.charAt(i) - 48;
int b = WEIGHTING_FACTOR[i];
sum += a * b;
}
int checkNum = sum % 11;
// System.out.println(checkNum);
final String[] CHECK_CODE = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; // 校验码
return check.equals(CHECK_CODE[checkNum]);
}
// 输出方法
public static void printInfo(String area, String birth, String gender, int age) {
System.out.println("-----身份证ID解析成功!-----");
System.out.println("该身份证持有人的地区码为:" + area +
"\n出生日期为:" + birth +
"\n性别为" + gender +
"\n当前年龄为:" + age);
}
}
首先会判断输入数字是否满足18位或15位,不满足直接抛出异常,之后再对15位转18位处理,在切割获得区域代码、生日,利用性别码判断出性别,最后通过生日计算当前年龄,最后输出,具体使用场景肯定不会这样调用,多用在从前端获取到身份证号后,后端直接进行解析该用户的信息,直接存于数据库,减少用户输入,并可以反馈给前端部分用户信息用作展示。