栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

hive自定义函数-身份证号合法性判断

hive自定义函数-身份证号合法性判断

hive自定义函数-身份证号合法性判断
  • 简要
  • 代码

简要

身份证号合法性判断:
若为18位身份证号:
1.第18位数字,应该在身份证号最后一位校验位数字中
2.前17为数字分别乘以对应的加权因子,累加,结果%11==17为数字
3.数字除18位外,全为数字
若位15位身份证号:
1.验证前6位是为行政区号
2.9-10位为月份<13
3.11-12位为日期<32
4.数据全为数字
注意:数据行政区号全部展示与代码中浏览器中打开时,会导致加载过慢卡顿,所以仅上传了部分数据,全量有*3271条行政区号,需要的评论留言

代码
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;

import java.util.*;


public class UdfIsIdcard extends UDF {
    
    
    @Description(
            name = "udf_is_idcard",
            value = "_FUNC_(str) - Returns str is idcard?0:1",
            extended = "Example:n  > SELECt _FUNC_('620121199701232548') FROM dual LIMIT 1;n   return    0 "
    )

    static int[] weights = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; // 新版身份证号 1-17 位的加权因子. 该数组顺序不能变,和index有对应关系
    static String[] checkCode = {"1","0","X","9","8","7","6","5","4","3","2"}; // 新身份证号最后一位校验位的值. 该数组顺序不能变,和index有对应关系
    static Set newIdCardNoLastNOSet = new HashSet(Arrays.asList(checkCode));
    static Set numberSet = new HashSet(Arrays.asList("9","8","7","6","5","4","3","2","1","0"));
    static Set areaCodeSet = new HashSet(Arrays.asList("110101","110102","110105"));


        public int evaluate(final String idCardNo) {
            if (!basicLegality(idCardNo.trim())) { // 身份证号基础校验不通过,返回false
                return 0;
            }
            if (oldIdCardNoValidate(idCardNo) || newIdCardNoValidate(idCardNo)) {
                return 1;
            }
            return 0;

        }
        
        private boolean basicLegality(String idCardNo) {
            if (StringUtils.isEmpty(idCardNo) || (idCardNo.length() != 15 && idCardNo.length() != 18)) { // 不是合格的身份证号,新版18位,旧版15位
                return false;
            }
            String number = idCardNo;
            if (idCardNo.length() == 18) { // 新身份证号18位,最后一位可能包含X,单独验证
                String lastNumber = idCardNo.substring(17).toUpperCase();
                boolean contains = newIdCardNoLastNOSet.contains(lastNumber);
                if (!contains) {
                    return false; // 如果不包含在这里面,那么验证不通过
                }
                number = number.substring(0, 17);
            }
            // 做数字验证
            for (int i = 0; i < number.length(); i++) {
                boolean contains = numberSet.contains(String.valueOf(number.charAt(i)));
                if (!contains) {
                    return false; // 如果不包含在这里面,那么验证不通过
                }
            }
            return true;
        }

        
        private  boolean newIdCardNoValidate(String newIdCardNo) {
//            if (StringUtils.isEmpty(newIdCardNo) || newIdCardNo.length() != 18) { // 不是合格的新版身份证号
//                return false;
//            }
            int sum = 0; // 此处用int即可。即使每位都是9,求和之后也远远不会溢出,达到int的最大值
            for (int i = 0; i < 17; i++) {
                int c = Integer.parseInt(String.valueOf(newIdCardNo.charAt(i)));
                sum += weights[i] * c;
            }
            int checkCodeIndex = sum % 11;
            return checkCode[checkCodeIndex].equalsIgnoreCase(newIdCardNo.substring(17));
        }



        
        private boolean oldIdCardNoValidate(String oldIdCardNo) {
            boolean flag = false;
//            if(StringUtils.isNotEmpty(oldIdCardNo)&& oldIdCardNo.length() == 15){
//
//            }

            if(areaCodeSet.contains(oldIdCardNo.substring(0,6)) && Integer.parseInt(oldIdCardNo.substring(8,10)) < 13 && Integer.parseInt(oldIdCardNo.substring(10,12)) <32){
                flag =true;
            }
            return flag;
        }

        public static void main(String[] args) {
            System.out.println("值为" + new  UdfIsIdcard().evaluate( "130503670241001"  ));
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/342748.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号