身份证号码验证

一、通过校验码(身份证号第18位)验证:

/*
身份证中第十八位数字的计算方法为:
1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7. 9 .10 .5. 8. 4. 2. 1. 6. 3. 7. 9. 10. 5. 8. 4. 2.
2.将这17位数字和系数相乘的结果相加。
3.用加出来和除以11,看余数是多少?
4余数只可能有0 、1、 2、 3、 4、 5、 6、 7、 8、 9、 10这11个数字。其分别对应的最后一位身份证的号码为1 .0. X. 9. 8. 7. 6. 5. 4. 3. 2.。
5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。
倒数第二位是用来表示性别的
例如:某男性的身份证号码是34052419800101001X。我们要看看这个身份证是不是合法的身份证。
首先:我们得出,前17位的乘积和是189
然后:用189除以11得出的结果是17 + 2/11,也就是说余数是2。
最后:通过对应规则就可以知道余数2对应的数字是x。所以,这是一个合格的身份证号码。
*/

public static boolean vIDNumByCode(String idNum) {
        // 系数列表
        int[] ratioArr = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        // 校验码列表
        char[] checkCodeList = {'1', '0', 'X', '9', '8', '7', '6', '5', '4',
                '3', '2'};
        // 获取身份证号字符数组
        char[] cIds = idNum.toCharArray();
        // 获取最后一位(身份证校验码)
        char oCode = cIds[ID_LENGTH];
        int[] iIds = new int[ID_LENGTH];
        int idSum = 0;// 身份证号第1-17位与系数之积的和
        int residue = 0;// 余数(用加出来和除以11,看余数是多少?)
        for (int i = 0; i < ID_LENGTH; i++) {
            iIds[i] = cIds[i] - '0';
            idSum += iIds[i] * ratioArr[i];
        }
        residue = idSum % 11;// 取得余数
        return Character.toUpperCase(oCode) == checkCodeList[residue];
}

 

二、使用正则表达式校验

1、 先来看身份证号的组成

(1)前1、2位数字表示:所在省份的代码;

(2)第3、4位数字表示:所在城市的代码;

(3)第5、6位数字表示:所在区县的代码;

(4)第7~14位数字表示:出生年、月、日;

(5)第15、16位数字表示:所在地的派出所的代码;

(6)第17位数字表示性别:奇数表示男性,偶数表示女性;

(7)第18位数字是校检码:用来检验身份证的正确性。校检码可以是0~10的数字,10用x表示。

2、通过一番研究得出如下表达式: 

 (1)^(1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|71|8[1-2])$ --> 身份证省级地区代码
 (2)^\\d{4}$ -------------------------------------------------> 市县级地区代码
 (3)^(19\\d{2}|20(0[0-9]|1[0-2]))$ -----------------------> 1900-2012 年
 (4)^(0(1|3|5|6|8)|1(0|2))(0[1-9]|[1-2][0-9]|30)$ ------------> 大月 (农历)
 (5)^(0(2|4|7|9)|11)(0[1-9]|[1-2][0-9])$ ---------------------> 小月 (农历)
 (6)^\\d{3}([0-9]|x|X)$ --------------------------------------> 后四位

3、上代码

public static boolean vIDNumByRegex(String idNum) {
        // 最多可以至当前年份 ,至于月份,日期 可自行添加
        String curYear = "" + Calendar.getInstance().get(Calendar.YEAR);
        int y3 = Integer.valueOf(curYear.substring(2, 3));// 年份第3位
        int y4 = Integer.valueOf(curYear.substring(3, 4));// 年份第4位
        // 过去的一个十年
        // 如:当前2014年 则 2000 - 2009
        // 当前2034年 则 2000 - 2029
        String pass10Year = "[0-" + (y3 - 1) + "][0-9]";
        // 当前的一个十年
        // 如:当前2014年 则 2010 - 2014
        // 当前2034年 则 2030 - 2034
        String cur10Year = y3 + "[0-" + y4 + "]";
        String yearRegexStr = "20(" + pass10Year + "|" + cur10Year + ")";
        return idNum
                .matches("^(1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|71|8[1-2])\\d{4}(19\\d{2}|"
                        + yearRegexStr
                        + ")(((0(1|3|5|6|8)|1(0|2))(0[1-9]|[1-2][0-9]|30))|((0(2|4|7|9)|11)(0[1-9]|[1-2][0-9])))\\d{3}([0-9]|x|X)$");
}

 

转载于:https://www.cnblogs.com/jacksBlogs/archive/2013/01/14/2859466.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值