中国二代居民身份证校验_编码正确性校验 java实现

规则

身份证18位分别代表的含义,身份证15位升级到18位,原来年用2位且没有最后一位,从左到右方分别表示
①1-2 升级行政区代码
②3-4 地级行政区划分代码
③5-6 县区行政区分代码
④7-10 11-12 13-14 出生年、月、日
⑤15-17 顺序码,同一地区同年、同月、同日出生人的编号,奇数是男性,偶数是女性
⑥18 校验码,如果是0-9则用0-9表示,如果是10则用X(罗马数字10)表示

参考

http://blog.csdn.net/embracejava/article/details/77341740

java实现

拿来即可使用

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

/**
 * 身份证号码正确性校验,默认18位身份证
 */
public class IdcardNumberCheckUtil {
    //省(直辖市)码表
    private static String provinceCode[] = { "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", "71", "81", "82", "91" };
    //身份证前17位每位加权因子
    private static int[] powFactor = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
    //身份证第18位校检码
    private static char[] verifyValue = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };

    /**
     * 身份证正则表达式
     * 1.以非0位开头的数字6位 1 -6位。①1-2 升级行政区代码 ②3-4 地级行政区划分代码 ③5-6 县区行政区分代码
     * 2.以19或20开头的的8位yyyymmdd的日期数据。 7 - 14位。
     * 3.15-17 顺序码,同一地区同年、同月、同日出生人的编号,奇数是男性,偶数是女性
     * 4.18 校验码,如果是0-9则用0-9表示,如果是10则用X(罗马数字10)表示
     */
    private static String pattern = "^[1-9][0-9]{5}(?:19|20)?[0-9]{2}(?:0[1-9]|1[012])(?:0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9Xx]?$";
    private static Pattern regex = Pattern.compile(pattern);

    public static boolean check(String idNum){
        idNum = idNum.toUpperCase();
        if(null == idNum || idNum.trim().length() != 18 ){
            return false;
        }
        char checkValue = getCheckValue(idNum);
        if(regex.matcher(idNum).find() && isValidProvinceId(idNum.substring(0,2)) && checkValue == idNum.charAt(17) && isValidDate(idNum.substring(6,14))){
            return true;
        }
        return false;
    }

    /**
     * 检查身份证的省份信息是否正确
     * @param provinceId
     * @return
     */
    private static boolean isValidProvinceId(String provinceId){
        for (String id : provinceCode) {
            if (id.equals(provinceId)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 校验一个日期的合法性,排除如2月30日这种日期
     * @param str
     * @return
     */
    private static boolean isValidDate(String str) {
        boolean convertSuccess=true;
    // 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写;
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        try {
        // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
            convertSuccess=false;
        }
        return convertSuccess;
    }

    private static char getCheckValue(String idNum)
    {
        int sum = 0;

        for (int i = 0; i < 17; i++)
        {
            sum = sum + Integer.parseInt(idNum.substring(i, i + 1)) * powFactor[i];
        }
        return verifyValue[sum % 11];
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值