Java身份证号脱敏、校验身份证号合法性、根据身份证号获取年龄、根据生日获取年龄


身份证号编码规则

第一、二位表示省(自治区、直辖市、特别行政区)。
第三、四位表示市(地级市、自治州、盟及国家直辖市所属市辖区和县的汇总码)。其中,01-20,51-70表示省直辖市;21-50表示地区(自治州、盟)。
第五、六位表示县(市辖区、县级市、旗)。01-18表示市辖区或地区(自治州、盟)辖县级市;21-80表示县(旗);81-99表示省直辖县级市。
第七、十四位表示出生年月日(单数字月日左侧用0补齐)。其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。
第十五、十七位表示顺序码。对同地区、同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。
第十八位表示校验码。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,校验码如果出现数字10,就用X(罗马字符)来代替。

  • 15位:6位地址码+6位出生年月日(900101代表1990年1月1日出生)+3位顺序码
  • 18位:6位地址码+8位出生年月日(19900101代表1990年1月1日出生)+3位顺序码+1位校验码

身份证号脱敏

/**
  * 身份证号脱敏
  * 保留前六后三, 适用于15位和18位身份证号
  *
  * @param idCard
  * @return String
  **/
public static String desensitizedIdCard(String idCard){
    if (StringUtils.isNotBlank(idCard)) {
        if (idCard.length() == 15){
            idCard = idCard.replaceAll("(\\w{6})\\w*(\\w{3})", "$1******$2");
        }
        if (idCard.length() == 18){
            idCard = idCard.replaceAll("(\\w{6})\\w*(\\w{3})", "$1*********$2");
        }
    }
    return idCard;
}

身份证号合法性校验

/**
 * 身份证号合法性校验
 *
 * @param idCard
 * @return String
 */
public static boolean isLegalIDCard(String idCard) {
  boolean res = false;
  // 校验规则(15或是18位身份证号码)
  if (isMatches(idCard)) {
      if (idCard.length() == 18) {
          char[] idCardArray = 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 total = 0;
          for (int i = 0; i < idCardWi.length; i++) {
              int count = Integer.parseInt(String.valueOf(idCardArray[i])) * idCardWi[i];
              total += count;
          }
          // 最后一位校验码
          int idCardModify = total % 11;
          if (idCardY[idCardModify].toUpperCase().equals(String.valueOf(idCardArray[17]).toUpperCase())) {
              res = true;
          } else {
              System.out.println(idCardY[idCardModify].toUpperCase());
              res = false;
          }
      } else {
          res = true;
      }
  }
  return res;
}

private static boolean isMatches(String idCard) {
  if (StringUtils.isBlank(idCard)) {
      return 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]$)|"
          + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
  return idCard.matches(regex);
}

根据身份证号获取年龄

/**
  * 根据身份证号获取年龄
  *
  * @param idCard
  * @return Integer
  */
 public static Integer getAgeByIdCard(String idCard) {
     boolean legalIDCard = isLegalIDCard(idCard);
     if (!legalIDCard) return null;
     Integer age = null;
     int year = Calendar.getInstance().get(Calendar.YEAR);
     if (idCard.length() == 15) {
         age = (year - Integer.parseInt("19" + idCard.substring(6, 8)));
     } else if (idCard.length() == 18) {
         age = (year - Integer.parseInt(idCard.substring(6, 10)));
     }
     return age;
 }

根据生日日期获取年龄

根据生日当天为分界线来计算年龄。

private static int getAgeByBirthday(LocalDate birthday) {
  int age = 0;
  try {
      Calendar now = Calendar.getInstance();
      now.setTime(new Date());// 当前时间
      now.setTimeInMillis(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());

      Calendar birth = Calendar.getInstance();
      birth.setTimeInMillis(birthday.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli());
      if (birth.after(now)) {// 如果传入的时间,在当前时间的后面,返回0岁
          age = 0;
      } else {
          age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR) - 1;
          if (now.get(Calendar.MONTH) >= birth.get(Calendar.MONTH)) {
              if (now.get(Calendar.DAY_OF_MONTH) >= birth.get(Calendar.DAY_OF_MONTH)) {
                  age += 1;
              }
          }
      }
      return age;
  } catch (Exception e) {
      return 0;
  }
}

根据身份证号获取年龄、生日的Map集合

/**
  * 根据身份证号获取年龄、生日的Map集合
  *
  * @param idCard
  * @return Map<String, Object>
  * @author wanglingqiang
  */
 public static Map<String, Object> getAgeBirthDayByIdCard(String idCard) {
     Map<String, Object> result = Maps.newHashMap();
     if (!isMatches(idCard)) return result;
     String birthdayStr = idCard.substring(6, 14);
     LocalDate birthday = LocalDate.parse(birthdayStr, DateTimeFormatter.ofPattern(Constants.SMALL_DATE_FORMAT));
     int age = getAgeByBirthday(birthday);
     result.put("age", age);
     result.put("birthday", birthday);
     return result;
 }

private static boolean isMatches(String idCard) {
  //上面写了
}

private static int getAgeByBirthday(LocalDate birthday) {
  //上面写了
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值