import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 身份证号码校验工具类
 *
 */
public class IdCardUtil {

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

// 每位加权因子
    private int power[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

// 第18位校检码
    private String verifyCode[] = {"1", "0", "X", "9", "8", "7", "6", "5",
            "4", "3", "2"};

private static DateFormat dateFormat_yyyyMMdd = new SimpleDateFormat("yyyyMMdd");

private static DateFormat dateFormat_yyyy = new SimpleDateFormat("yyyy");

/**
     * <p>
     * 判断18位身份证的合法性
     * </p>
     * 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
     * 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
     * <p>
     * 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。
     * </p>
     * <p>
     * 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码;
     * 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码;
     * 6.第17位数字表示性别:奇数表示男性,偶数表示女性;
     * 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。
     * </p>
     * <p>
     * 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4
     * 2 1 6 3 7 9 10 5 8 4 2
     * </p>
     * <p>
     * 2.将这17位数字和系数相乘的结果相加。
     * </p>
     * <p>
     * 3.用加出来和除以11,看余数是多少?
     * </p>
     * 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3
     * 2。
     * <p>
     * 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。
     * </p>
     *
     * @param idcard
     * @return
     */
    public boolean isValidate18Idcard(String idcard) {

// 1.非18位为假
        if (idcard.length() != 18) {
            return false;
        }

// 2.前两位区域代码校验
        if(!zoneNum.containsKey(Integer.valueOf(idcard.substring(0, 2)))){
            return false;
        }

// 3.校验年份
        String year = idcard.substring(6, 10);
        final int iyear = Integer.parseInt(year);
        if (iyear < 1900 || iyear > Calendar.getInstance().get(Calendar.YEAR)) {
            return false;// 1900年的PASS,超过今年的PASS
        }

// 4.校验月份
        String month = idcard.substring(10, 12);
        final int imonth = Integer.parseInt(month);
        if (imonth < 1 || imonth > 12){
            return false;
        }

// 5.校验天数
        String day = idcard.substring(12, 14);
        final int iday = Integer.parseInt(day);
        if (iday < 1 || iday > 31) {
            return false;
        }

// 6.计算余数
        // 获取前17位
        String idcard17 = idcard.substring(0, 17);
        // 获取第18位
        String idcard18Code = idcard.substring(17, 18);
        char c[] = null;
        String checkCode = "";
        // 是否都为数字
        if (isDigital(idcard17)) {
            c = idcard17.toCharArray();
        } else {
            return false;
        }

if (null != c) {
            int bit[] = new int[idcard17.length()];
            bit = converCharToInt(c);
            int sum17 = 0;
            sum17 = getPowerSum(bit);
            // 将和值与11取模得到余数进行校验码判断
            checkCode = getCheckCodeBySum(sum17);
            if (null == checkCode) {
                return false;
            }
            // 将身份证的第18位与算出来的校码进行匹配,不相等就为假
            if (!idcard18Code.equalsIgnoreCase(checkCode)) {
                return false;
            }
        }
        return true;
    }

/**
     * 数字验证
     *
     * @param str
     * @return
     */
    public boolean isDigital(String str) {
        return str == null || "".equals(str) ? false : str.matches("^[0-9]*$");
    }

/**
     * 将身份证的每位和对应位的加权因子相乘之后,再得到和值
     *
     * @param bit
     * @return
     */
    public int getPowerSum(int[] bit) {

int sum = 0;

if (power.length != bit.length) {
            return sum;
        }

for (int i = 0; i < bit.length; i++) {
            for (int j = 0; j < power.length; j++) {
                if (i == j) {
                    sum = sum + bit[i] * power[j];
                }
            }
        }
        return sum;
    }

/**
     * 将和值与11取模得到余数进行校验码判断
     *
     * @param checkCode
     * @param sum17
     * @return 校验位
     */
    public String getCheckCodeBySum(int sum17) {
        String checkCode = null;
        switch (sum17 % 11) {
            case 10:
                checkCode = "2";
                break;
            case 9:
                checkCode = "3";
                break;
            case 8:
                checkCode = "4";
                break;
            case 7:
                checkCode = "5";
                break;
            case 6:
                checkCode = "6";
                break;
            case 5:
                checkCode = "7";
                break;
            case 4:
                checkCode = "8";
                break;
            case 3:
                checkCode = "9";
                break;
            case 2:
                checkCode = "x";
                break;
            case 1:
                checkCode = "0";
                break;
            case 0:
                checkCode = "1";
                break;
        }
        return checkCode;
    }

/**
     * 将字符数组转为整型数组
     *
     * @param c
     * @return
     * @throws NumberFormatException
     */
    public int[] converCharToInt(char[] c) throws NumberFormatException {
        int[] a = new int[c.length];
        int k = 0;
        for (char temp : c) {
            a[k++] = Integer.parseInt(String.valueOf(temp));
        }
        return a;
    }

// 1-男,0-女,9-其他
    public static String getSex(String idcard) throws Exception {
        // 获取性别
        if (idcard.length() == 18) {
            return (Integer.parseInt(idcard.substring(16, 17)) % 2 != 0) ? "1" : "0";
        }
        return "9";
    }

// 获取生日
    public static Date getBirthday(String idcard) throws Exception {
        // 获取出生日期
        String birthday = idcard.substring(6, 14);
        return dateFormat_yyyyMMdd.parse(birthday);
    }

// 获取年龄
    public static int getAge(String idcard) throws Exception {
        String birthday = idcard.substring(6, 14);
        Date birthdate = dateFormat_yyyyMMdd.parse(birthday);
        GregorianCalendar currentDay = new GregorianCalendar();
        currentDay.setTime(birthdate);
        return Integer.parseInt(dateFormat_yyyy.format(new Date())) - currentDay.get(Calendar.YEAR);
    }

public static void main(String[] args) throws Exception {

String idcard18 = "110112198111024513";//18位
        IdCardUtil iv = new IdCardUtil();
        System.out.println(iv.isValidate18Idcard(idcard18));
    }
}

java身份证工具类,身份证合法性校验,根据身份证获取生日、年龄、性别相关推荐

  1. Java 正则表达式 工具类 中文 英文 email 手机号 身份证 数字 日期

    大家好,我是烤鸭: 分享一个Java版本的正则校验工具类. Validation.java package com.xxx.xxx.common.utils;import java.util.rege ...

  2. Java手机号码工具类(判断运营商、获取归属地)

    所需引用Jar包 <dependency><groupId>com.googlecode.libphonenumber</groupId><artifactI ...

  3. Java手机号码工具类(判断运营商、获取归属地)以及简要的原理跟踪

    最近做的项目有一部分关于手机号码的操作,于是搜罗了一些资料,整了一个工具类.主要有以下三个功能:判断号码是否有效.获取号码运营商.获取号码归属地. 首先需要引入google开发的相关依赖或者下载对应的 ...

  4. java身份证工具类(校验身份证是否合法、通过身份证获取年龄、性别、生日,将15位身份证转为18位等)

    一.简介 因为工作需要经常用到身份证做一些相关操作,于是通过查阅资料总结出一些常用的工具方法,包括校验身份证是否合法.通过身份证获取年龄.通过身份证获取性别.通过身份证获取户籍地址.通过身份证获取生日 ...

  5. Java 身份证工具类

    2019独角兽企业重金招聘Python工程师标准>>> import java.text.ParseException; import java.text.SimpleDateFor ...

  6. Java 工具类 - 身份证工具类 IDCardUtil

    先来了解一下身份证的组成规则: 1.号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码 ...

  7. 身份证工具类-获取性别、年龄、出生日期

    package com.kotei.aptiv.common.core.util;import org.apache.commons.lang3.StringUtils;import java.uti ...

  8. java 图形校验_java图形验证码生成工具类 web页面校验验证码

    java图形验证码生成工具类 web页面校验验证码 发布于 2020-7-14| 复制链接 摘记: 最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善.验证码生成器: ```java i ...

  9. JAVA常用工具类(实用高效)

    JAVA常用工具类(根据GITHUB代码统计) 从Google你能搜索到大量的关于Struts,Spring,Hibernate,iBatis等比较大的框架的资料,但是很少有人去关注一些小的工具包,但 ...

  10. Java 常用工具类整理

    目录 第一部分:常用的16个工具类 第二部分:java开发常用工具类(正则校验) 第一部分:常用的16个工具类 一.org.apache.commons.io.IOUtils 1.closeQuiet ...

最新文章

  1. cxf 本地wsdl_cxf使用wsdl文件生成代码
  2. “References to generic type List should be parameterized”
  3. [蓝桥杯][算法训练VIP]麦森数(Java大数+快速幂)
  4. Java输出特定时间段特定格式时间信息
  5. (98)利用函数function实现半字节加法功能,面试必问(二十二)(第20天)
  6. 如何在Ubuntu里安装Helm 1
  7. Android自定义控件封装之自定义属性的实现
  8. SSL的作用与目前主流的使用场景介绍
  9. emos mysql_企业邮件部署详细步骤(EMOS)
  10. c语言 sub(),C语言考试试题
  11. 苹果笔记本能玩英雄联盟吗_英雄联盟手游要上线了,王者荣耀还会有人玩吗
  12. 将python 脚本转换为exe格式
  13. c语言编程多项式,多项式c语言编程.docx
  14. Linux内核4.14版本——mmc core(2)——bus模块
  15. Table does not have the identity property. Cannot perform SET operation.
  16. Qt解决资源文件中添加图片,对应控件不显示图片的问题
  17. 马尔可夫决策过程(Markov Decision Process, MDP)
  18. 梦幻新诛仙微信绑定没有服务器,独乐乐不如众乐乐,在《梦幻新诛仙》里交朋友居然这么简单?...
  19. RabbitMQ 客户端源码系列 - Channel
  20. python关键词挖掘_关键词挖掘,挖掘关键词的方法

热门文章

  1. H.264/AVC 的分层结构与画面划分
  2. 笔记/5个你现在可以使用的 ES2019 特性
  3. 电脑只有飞行模式,没有WIFI列表
  4. k30s刷鸿蒙系统,最好的LCD屏手机!Redmi K30S至尊纪念版今天发布:144Hz高刷、7档变速...
  5. 用python做了一个绝地求生外g???
  6. 运用移动BI提升企业运用效率
  7. 物联网技术有望为新能源消纳提供一系列解决方案
  8. 实体相交,切割空间的方法,建筑师编程指南-sketchup插件04
  9. image与base64相互转换
  10. 【附源码】Java计算机毕业设计渔具店管理系统(程序+LW+部署)