JAVA判断18位身份证的合法性的工具类

根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。(顺序码:
表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。)

第1、2位数字表示:所在省份的代码;
第3、4位数字表示:所在城市的代码;
第5、6位数字表示:所在区县的代码;
第7~14位数字表示:出生年、月、日;
第15、16位数字表示:所在地的派出所的代码;
第17位数字表示性别:奇数表示男性,偶数表示女性;

第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。

第十八位数字(校验码)的计算方法为:
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。所以如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。

省、直辖市代码表:
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 : 国外

private static StringcityCode[] = {"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 power[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};

/*校验方法*/

public static boolean validate18Idcard(String idcard) {

if (idcard ==null) {

return false;

}

// 非18位为假

if (idcard.length() !=18) {

return false;

}

// 获取前17位

String idcard17 = idcard.substring(0,17);

// 前17位全部为数字

if (!isDigital(idcard17)) {

return false;

}

String provinceid = idcard.substring(0,2);

// 校验省份

    if (!checkProvinceid(provinceid)) {

return false;

}

// 校验出生日期

    String birthday = idcard.substring(6,14);

SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMdd");

try {

Date birthDate = sdf.parse(birthday);

String tmpDate = sdf.format(birthDate);

if (!tmpDate.equals(birthday)) {// 出生年月日不正确

            return false;

}

}catch (ParseException e1) {

return false;

}

// 获取第18位

    String idcard18Code = idcard.substring(17,18);

char c[] = idcard17.toCharArray();

int bit[] =converCharToInt(c);

int sum17 =0;

sum17 =getPowerSum(bit);

// 将和值与11取模得到余数进行校验码判断

    String checkCode =getCheckCodeBySum(sum17);

if (null == checkCode) {

return false;

}

// 将身份证的第18位与算出来的校码进行匹配,不相等就为假

    if (!idcard18Code.equalsIgnoreCase(checkCode)) {

return false;

}

return true;

}

/* 数字验证*/

private static boolean isDigital(String str) {

 return str.matches("^[0-9]*$");

}

/*校验省份*/

private static boolean checkProvinceid(String provinceid) {

     for (String id : cityCode) { 

        if (id.equals(provinceid)) {

             return true;

         } 

    } 

return false;

}

/* 将字符数组转为整型数组*/

private static int[] converCharToInt(char[] c)throws NumberFormatException {

int[] a =new int[c.length];

int k =0;

for (char temp : c) {

a[k++] = Integer.parseInt(String.valueOf(temp));

}

return a;

}

/* 将身份证的每位和对应位的加权因子相乘之后,再得到和值*/

private static int getPowerSum(int[] bit) {

int sum =0;

if (power.length != bit.length) {

return sum;

}

for (int i =0; i < bit.length; i++) {

for (int j =0; j

if (i == j) {

sum = sum + bit[i] *power[j];

}

}

}

return sum;

}

/*将和值与11取模得到余数进行校验码判断*/

private static String getCheckCodeBySum(int sum17) {

String checkCode =null;

switch (sum17 %11) {

case 10:

checkCode ="2";

break;

case 9:

checkCode ="3";

break;

case 8:

checkCode ="4";

break;

case 7:

checkCode ="5";

break;

case 6:

checkCode ="6";

break;

case 5:

checkCode ="7";

break;

case 4:

checkCode ="8";

break;

case 3:

checkCode ="9";

break;

case 2:

checkCode ="x";

break;

case 1:

checkCode ="0";

break;

case 0:

checkCode ="1";

break;

}

return checkCode;

}

写个main测试一下

public static void main(String[] args)throws Exception {

String idcard18 = "310103198811155044";

 logger.info("isValidatedAllIdcard[{}]",isValidatedAllIdcard(idcard18));

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值