首页 > 编程语言 >Java身份证校验工具类

Java身份证校验工具类

时间:2022-10-15 23:02:12浏览次数:60  
标签:10 provinces return String IdCard 校验 身份证 put Java


Java身份证校验工具类

工作中经常会涉及到身份证的校验,而且需求不同,有的需要校验最后一位校验位,有的不需要,这里参考了几篇文章及自己工作中用到的情况写了一个工具类。记录一下,菜鸟一个,大佬勿喷。
这里只考虑18位身份证

public class IdCardValidateUtils {

/** 省份开头字典 */
private static Map<Integer, String> provinces = new HashMap<>();
static {
provinces.put(11, "北京");
provinces.put(12, "天津");
provinces.put(13, "河北");
provinces.put(14, "山西");
provinces.put(15, "内蒙古");
provinces.put(21, "辽宁");
provinces.put(22, "吉林");
provinces.put(23, "黑龙江");
provinces.put(31, "上海");
provinces.put(32, "江苏");
provinces.put(33, "浙江");
provinces.put(34, "安徽");
provinces.put(35, "福建");
provinces.put(36, "江西");
provinces.put(37, "山东");
provinces.put(41, "河南");
provinces.put(42, "湖北 ");
provinces.put(43, "湖南");
provinces.put(44, "广东");
provinces.put(45, "广西");
provinces.put(46, "海南");
provinces.put(50, "重庆");
provinces.put(51, "四川");
provinces.put(52, "贵州");
provinces.put(53, "云南");
provinces.put(54, "西藏 ");
provinces.put(61, "陕西");
provinces.put(62, "甘肃");
provinces.put(63, "青海");
provinces.put(64, "宁夏");
provinces.put(65, "新疆");
provinces.put(71, "台湾");
provinces.put(81, "香港");
provinces.put(82, "澳门");
}

/**
* @description 简单校验满足非空及18位,无法校验到月份对应天数
* @date 2022/10/10 16:52
* @param
* @param IdCard
* @return boolean
*/
public static boolean easyCheckIdCard(String IdCard) {
//字符串为空或者不符合简单的18位校验返回false
String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
if (StringUtils.isBlank(IdCard) || !Pattern.matches(regex, IdCard)) {
return false;
}
return true;
}


/**
* @description 中级校验,不校验最后一位
* @date 2022/10/10 16:57
* @param
* @param IdCard
* @return boolean
*/
public static boolean middleCheckIdCard(String IdCard) {
return (easyCheckIdCard(IdCard) && checkBirthday(IdCard) && checkProvince(IdCard));
}

/**
* @description 高级校验包含校验位
* @date 2022/10/10 16:57
* @param
* @param IdCard
* @return boolean
*/
public static boolean highCheckIdCard(String IdCard) {
return (middleCheckIdCard(IdCard) && checkLastNumber(IdCard));
}

/**
* @description 身份证校验位的校验
* @date 2022/10/10 15:16
* @param
* @param IdCard
* @return boolean
*/
public static boolean checkLastNumber(String IdCard) {
try {
char[] charArray = IdCard.toCharArray();
//前十七位加权因子
int[] IdCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
//这是除以11后,可能产生的11位余数对应的验证码
String[] IdCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
int sum = 0;
for (int i = 0; i < IdCardWi.length; i++) {
int current = Integer.parseInt(String.valueOf(charArray[i]));
int count = current * IdCardWi[i];
sum += count;
}
char IdCardLast = charArray[17];
int IdCardMod = sum % 11;
return IdCardY[IdCardMod].toUpperCase().equals(String.valueOf(IdCardLast).toUpperCase());
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* @description 年月日校验
* @date 2022/10/10 16:48
* @param
* @param IdCard
* @return boolean
*/
public static boolean checkBirthday(String IdCard) {
String yearRegex = "(18|19|20)\\d{2}";
String monthRegex = "(0[1-9])|10|11|12";
String dayRegex = "([0-2][1-9])|10|20|30|31";
String year = IdCard.substring(6, 10);
if (!Pattern.matches(yearRegex, year)) {
return false;
}
String month = IdCard.substring(10, 12);
if (!Pattern.matches(monthRegex, month)) {
return false;
}
String day = IdCard.substring(12, 14);
if (!Pattern.matches(dayRegex, day)) {
return false;
}
Integer yearInt = Integer.parseInt(year);
Integer monthInt = Integer.parseInt(month);
Integer dayInt = Integer.parseInt(day);
switch (monthInt) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return true;
case 2:
if (leapYear(yearInt)) {
//闰年 29
return dayInt <= 29;
}
return dayInt <= 28;
default:
return dayInt <= 30;
}
}

/**
* @description 校验是否为闰年
* @date 2022/10/10 15:39
* @param
* @param year
* @return boolean
*/
public static boolean leapYear(int year) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
return true;
}
return false;
}

/**
* @description 身份证省份的校验,这里默认符合简单的18位校验
* @date 2022/10/10 15:18
* @param
* @param IdCard
* @return boolean
*/
public static boolean checkProvince(String IdCard) {
String pattern = "^[1-9][0-9]";
String prov = IdCard.substring(0, 2);
if (Pattern.matches(pattern, prov)) {
return provinces.containsKey(Integer.parseInt(prov));
}
return false;
}

}


标签:10,provinces,return,String,IdCard,校验,身份证,put,Java
From: https://blog.51cto.com/zhangmh/5759378

相关文章

  • 基于JavaEE的企业制度管理系统的设计与实现-计算机毕业设计源码+LW文档
    摘要:本企业制度管理系统是针对目前企业制度管理的实际需求,从实际工作出发,对过去的企业制度管理系统存在的问题进行分析,完善用户的使用体会。采用计算机系统来管理信息,取代人......
  • redis bitmap数据结构之java对等操作
    在之前的文章中,我们有说过bitmap,bitmap在很多场景可以应用,比如黑白名单,快速判定,登录情况等等。总之,bitmap是以其高性能出名。其基本原理是一位存储一个标识,其他衍生知......
  • JavaScript --- 随机点名抽奖系统
    1<!DOCTYPEhtml>2<htmllang="en">34<head>5<metacharset="UTF-8">6<metahttp-equiv="X-UA-Compatible"content="IE=edge">7<metan......
  • Java Mysql客户端 Mybatis-Plus 4步快速接入
    1,pom增加依赖<dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>......
  • Java数据结构学习之栈Stack
    Stack学习背景:在刷算法题中有个模块是针对栈结构的算法,而且在很多代码底层总也用到栈stack的数据结构,所以在此简单记录一下。介绍:栈(Stack)是一种后进先出(LIFO:LastIn......
  • Java中for循环中用break是跳出内层循环还是外层循环
    背景:我们知道:for循环中常用“continue”跳过当前循环执行下个循环,常用“break”跳出循环,但是在for循环嵌套中break是仅跳出内层循环还是跳出所有循环呢?测试:public......
  • ZKFinger Live20R 版对接java - B/S(ZKFinger SDK 5.0.0.32 )
     中控指纹采集器java版本具体实现官网已经给了demo,可以自行看下。接下来是我在此基础上将demo改成接口的形式,供页面调用。指纹采集页面:​编辑​效果图:编辑代码概述:1、去除......
  • Java并发编程学习6-同步容器类和并发容器
    本篇开始将要介绍Java平台类库下的一些最常用的并发基础构建模块,以及使用这些模块来构造并发应用程序时的一些常用模式。同步容器类同步容器类包括Vector和Hashtab......
  • Java只有值传递!!!
    记录一下!才知道java中没有引用传递!!首先看什么是值传递和引用传递值传递(passbyvalue)值传递是指在调用方法时将实参复制一份传递到方法中,这样当方法对形参进行修改时......
  • 温控采集器对接-java版-modbus4j
    @​​TOC​​​​​​看此文说明你已经了解了modbus协议,这里不再赘述​​业务需求采集冷柜温控采集器的温度,web端显示各个冷柜的温度(​​定时采集​​)需求分析1,采集温度2.......