记录一个根据身份证处理的具体工具

package com.hf.mypractice.utils;import jodd.datetime.JDateTime;import jodd.datetime.Period;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.StringUtils;import org.springframewor...
摘要由CSDN通过智能技术生成
package com.hf.mypractice.utils;

import jodd.datetime.JDateTime;
import jodd.datetime.Period;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Date: 2019/3/27
 * @Auther:
 */
@Slf4j
public class CommonUtil {

    /**
     * 身份证正则 15位
     */
    private final static String IDENTITY_CARD_15 = "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$";
    /**
     * 身份证正则 18位
     */
   private final static String IDENTITY_CARD_18 = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}(\\d|[xX])$"


    /**
     * 15位身份证从第一位到15位对应的系数分别为:从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
     */
    private static final int[] widthArr = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    /**
     * 第18位校验码数组
     */
    private static final String[] checkArr = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };

    /**
     *校验身份证的合法性
     * @return
     */
    public static Boolean checkIdentityCard(String identityCard){
        Boolean isOk = false;
        if(StringUtils.isNotEmpty(identityCard)){
            identityCard = identityCard.trim();
            if(identityCard.length() == 15){
                isOk = RegexUtil.check(identityCard, IDENTITY_CARD_15);
            }else{
                isOk = RegexUtil.check(identityCard,IDENTITY_CARD_18);
            }
        }
        return isOk;
    }

    /**
     * 通过身份证获取性别
     * @return 0.身份证不合法 1.男性 2.女性
     */
    public static Integer getGenderByIdentityCard(String identityCard){
        //校验身份证
        Boolean isOk = checkIdentityCard(identityCard);
        Integer sexNum = 0;
        if(isOk){
            if (15 == identityCard.length()) {
                // 15位身份证 最后一位表示性别
                sexNum = Integer.valueOf(identityCard.substring(14));
            } else if (18 == identityCard.length()) {
                //18位身份证 17位表示性别
                sexNum = Integer.valueOf(identityCard.substring(16, 17));
            }
            sexNum = (sexNum & 1) != 1 ? 2 : 1;
        }
        return sexNum;
    }

    /**
     * 15位:6位地址码+6位出生年月日(900101代表1990年1月1日出生)+3位顺序码
     * 18位:6位地址码+8位出生年月日(19900101代表1990年1月1日出生)+3位顺序码+1位校验码
     * @return   错误码 10001
     */
    public static Integer getAgeByIdentityCard(String identityCard){
        //校验身份证
        identityCard = identityCard.trim();
        Boolean isOk = checkIdentityCard(identityCard);
        Integer age = 10001;
        if(isOk){
            if(identityCard.length() == 15){
                //转换为18位
                identityCard = card15To18(identityCard);
            }
           //获取出生年月
            Date birthday = getBirthdayByIdentityCard(identityCard);
            if(null != birthday){
                //计算时间差
                JDateTime currTime = new JDateTime(System.currentTimeMillis());
                JDateTime birthdayTime = new JDateTime(birthday);
                Period period = new Period(birthdayTime,currTime);
                long days = period.getDays();
               log.info("相差的天数为:" + days);
                age = Integer.parseInt(days / 365 + "") + 1;
            }
        }
        return age;
    }

    /**
     * 根据身份证获取出生日期
     * @param identityCard
     * @return
     */
    public static Date getBirthdayByIdentityCard(String identityCard){
        //校验合法
        Boolean isOk = checkIdentityCard(identityCard);
         Date birthday = null;
        if(isOk){
            identityCard = identityCard.trim();
            String birthdayString = null;
            if(identityCard.length() == 15){
                //转换为18位
                identityCard = card15To18(identityCard);
            }
            //18位:6位地址码+8位出生年月日(19900101代表1990年1月1日出生)+3位顺序码+1位校验码
            birthdayString = identityCard.substring(6,14);
            birthday = dateStringFormat(birthdayString);
        }
        return birthday;
    }


    /**
     * 日期字符串格式化
     * @param dateString
     * @return
     */
    public static Date dateStringFormat(String dateString){
        Date date = null;
        if(StringUtils.isNotEmpty(dateString)){
            JDateTime jDateTime = new JDateTime(dateString,"YYYYMMDD");
            date = jDateTime.convertToDate();
        }
        return date;
    }


    /**
     * 将15位身份证转换为18位
     * @return  如果不是15位身份证,或者不合法将输出null,否则输出转换的18位身份证号码
     */
    public static String card15To18(String identityCard){
        String result = null;
        if(StringUtils.isNotEmpty(identityCard)){
            identityCard = identityCard.trim();
            if(identityCard.length() == 15){
                //校验合法性
                Boolean isOk = checkIdentityCard(identityCard);
                if(isOk){
                    /*转换开始*/
                    //完善年份
                    String card17 = identityCard.substring(0,6) + "19" + identityCard.substring(6);
                    //获取第18位的校验码
                    /*获取校验码索引的逻辑是,前提是先要得到17位的,将每一位的值乘以对应的系数,累加起来,模以11得到的*/
                    int sum = 0;
                    for (int i = 0; i < card17.length(); i++) {
                        sum += Integer.parseInt(card17.substring(i,i+1))*widthArr[i];
                    }
                    int checkIndex = sum % 11;
                    result = card17 + checkArr[checkIndex];
                }
            }
        }
        return result;
    }


    /**
     * 根据身份证获取到身份证所在的省市/市县信息
     * @param identityCard
     * @return  查找到了就返回值,否则返回null
     */
    public static String getAdressByIdentityCard(String identityCard){
        List<String> resultList = new ArrayList<>();
        if(StringUtils.isNotEmpty(identityCard)){
            identityCard = identityCard.trim();
            //校验身份证
            Boolean isOk = checkIdentityCard(identityCard);
            if(isOk){
                //截取前6位
                String prefixCard = identityCard.substring(0,6);
                //解析配置
                List<AreaNameDto> list = AreaStringUtil.parseArea();
                list.stream().forEach(var -> {
                    Map<String, String> map = var.getMap();
                    if(map.containsKey(prefixCard)){
                        resultList.add(map.get(prefixCard));
                        return;
                    }
                });
            }
        }
     return CollectionUtils.isEmpty(resultList) ? null:resultList.get(0);
    }


    public static void main(String[] args) {

    String card = "";
        System.out.println(getAdressByIdentityCard(card));


    }








}

获取省市的工具类:

package com.hf.mypractice.utils;

import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * @Description:   身份证前六位对应的地区处理
 * @Date: 2019/3/28
 * @Auther: 
 */
public class AreaStringUtil {

    /**
     * 解析地区的正则表达式
     */
    public static final String AREA_REGEX = "(\\d{6}(.){1}([\\u4e00-\\u9fa5]+))";

    /**身份证前两位代表的省份/直辖市
     * 11北京市、12天津市、13河北省、14山西省、15 内蒙古自治区;
     * 21辽宁省、22吉林省、23黑龙江省;
     * 31上海市、32江苏省、33浙江省、34安徽省、35福建省、36 江西省、37山东省;
     * 41河南省、42湖北省、43湖南省、44广东省、45广西壮族自治区、46海南省;
     * 50重庆市、51 四川省、52 贵州省。
     * 53 云南省、54西藏自治区;
     * 61 陕西省、62甘肃省、63 青海省、64 宁夏回族自治区、65新疆维吾尔自治区;
     */

    private static String[] parentCodeArr = null;

    private static String[] parentNameArr = null;


   private static final Map<String,String> parentMap = new HashMap<>();


   static{
        //获取注解上的值
       Field[] fields = ProvinceCodeModel.class.getDeclaredFields();
       //过滤final和static字段,并且需要有指定注解的
       Arrays.stream(fields).filter((Field field) -> !Modifier.isFinal(field.getModifiers()) && !Modifier.isStatic(field.getModifiers()) && field.isAnnotationPresent(ProvinceCode.class)).forEach(var -> {
           parentNameArr = var.getAnnotation(ProvinceCode.class).names();
           parentCodeArr = var.getAnnotation(ProvinceCode.class).codes();
       });

       for (int i = 0; i < parentCodeArr.length; i++) {
           parentMap.put(parentCodeArr[i],parentNameArr[i]);
       }
   }




    /**
     * 获取字段的值
     * @return
     */
    public static List<String> getAreaString(){
       //获取该类的所有字段
        Field[] fields = AreaStringUtil.class.getDeclaredFields();
        List<String> list = new ArrayList<>();
        Arrays.stream(fields).filter((Field field) -> !Modifier.isFinal(field.getModifiers()) && field.isAnnotationPresent(ParseString.class)).forEach(ff -> {
                ff.setAccessible(true);
           try {
               String value = (String) ff.get(ff.getName());
               list.add(value);
           } catch (IllegalAccessException e) {
               e.printStackTrace();
           }
       });
        return list;
    }




    /**
     * 正则解析,得到身份证前六位代号和对应的地区
     * @return
     */
    public static List<AreaNameDto> parseArea(){
        //获取数据
        List<String> list = getAreaString();

       List<AreaNameDto> resultList = new ArrayList<>();
        list.stream().forEach(areaString -> {
        Map<String,String> map = new HashMap<>();
        //正则解析
            /*parseList的格式是: 110101 东城区*/
         List<String> parseList = RegexUtil.matchs(areaString, AREA_REGEX, 1);
          if(!CollectionUtils.isEmpty(parseList)){
              parseList.stream().forEach(var -> {
                  String[] tempArr = var.split(" ");
                  Map<String, String> tempMap = new HashMap<>();
                  //获取前两位身份证号码
                  String address = "";
                  String shortCode = areaString.substring(0,2);
                  if(parentMap.containsKey(shortCode)){
                      address = parentMap.get(shortCode) + tempArr[1];
                  }
                  tempMap.clear();
                  tempMap.put(tempArr[0],address);
                  AreaNameDto dto = new AreaNameDto(parentMap.get(shortCode),tempMap);
                  resultList.add(dto);
              });
          }
        });
        return resultList;
    }





    public static void main(String[] args) {
        List<AreaNameDto> list = parseArea();
        list.stream().forEach
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值