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;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值