You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
4.5 KiB
99 lines
4.5 KiB
package com.hfkj.common.utils;
|
|
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
/**
|
|
* @ClassName IdCardUtil
|
|
* @Description
|
|
* @Author 杜江
|
|
* @Date 2020/8/11 11:38
|
|
* @Version 1.0
|
|
*/
|
|
public class IdCardUtil {
|
|
public static boolean isIdCard(String card){
|
|
card = replaceBlank(card);
|
|
if(card == null || "".equals(card)){
|
|
return false;
|
|
}
|
|
//定义 叛别用户 身份证号的正则表达式 (15位 或 18位,最后一位可以为字母)
|
|
String requal = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|(10|20|30|31))\\d{3}[0-9Xx]$)|"
|
|
+"(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
|
|
|
|
// 假设18位 身份证号码:
|
|
// ^ 表示开头
|
|
// [1-9] 第一位1-9 中的一个 4 注意!! 前六位代表地址,此处是 拆分 讲解 对正则 的注释
|
|
// \\d{5} 五位数字 10001(前六位省市县地区)
|
|
// (18|19|20) 19 (现阶段可能取值范围18xx-20xx年)
|
|
// \\d{2} 91 (年份)
|
|
// ((0[1-9])|(10|11|12)) 01(月份)
|
|
// (([0-2][1-9])|10|20|30|31) 01(日期) 也可写成(([0-2][1-9])|(10|20|30|31))
|
|
// \\d{3} 三位数字 123(第十七位奇数表示男,偶数表示女)
|
|
// [0-9Xx] 0123456789Xx 其中的一个 X(第十八位为校验值)
|
|
// $结尾
|
|
|
|
// 假设15位身份证号码: 410001910101123
|
|
// ^ 开头
|
|
// [1-9] 第一位1-9中的一个 4
|
|
// \\d{5} 五位数字 10001(前六位省市县地区)
|
|
// \\d{2} 91(年份) 表示 91年
|
|
// ((0[1-9])|(10|11|12)) 01(月份)
|
|
// (([0-2][1-9])|10|20|30|31) 01(日期)
|
|
// \\d{3} 123(第十五位奇数代表男,偶数代表女),15位身份证不含X
|
|
// $结尾
|
|
boolean matches = card.matches(requal);
|
|
|
|
//判断 第 18位 校验值 ,校验算法涉及两次mod 11的过程
|
|
// 二代身份证中的 号码第十八位的计算方法为:
|
|
if(matches){
|
|
if (card.length() == 18){
|
|
try {
|
|
char[] charArray = card.toCharArray();
|
|
//1,将前面的身份证号码17位数分别乘以不同的系数,系数为此处的 加权因子
|
|
//前十七位加权因子
|
|
int[] idCardWi = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
|
|
int sum = 0;
|
|
// 2,将这17位数字 和系数相乘 的结果相加
|
|
for (int i = 0;i < idCardWi.length;i++){
|
|
int current = Integer.parseInt(String.valueOf(charArray[i]));
|
|
// 相乘对应的 加权因子系数
|
|
int count = current * idCardWi[i];
|
|
// 结果相加
|
|
sum += count;
|
|
}
|
|
char idCardLast = charArray[17];
|
|
// 3,结果和 除以11,查看余数
|
|
int idCardMod = sum % 11;
|
|
// 4,这是除以 11后,可能产生的 11位余数对应的验证码(--对应下标),其中 X 代表罗马数字 10
|
|
String[] idCardY = {"1","0","X","9","8","7","6","5","4","3","2"};
|
|
if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())){
|
|
return true;
|
|
}else {
|
|
System.out.println("身份证最后一位:"+String.valueOf(idCardLast).toUpperCase()+
|
|
"错误,正确的应该是:"+idCardY[idCardMod].toUpperCase());
|
|
return false;
|
|
}
|
|
}catch (Exception e){
|
|
e.printStackTrace();
|
|
System.out.println("异常:"+card);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return matches;
|
|
}
|
|
|
|
public static String replaceBlank(String str) {
|
|
String dest = "";
|
|
if (str!=null) {
|
|
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
|
|
Matcher m = p.matcher(str);
|
|
dest = m.replaceAll("");
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println(isIdCard("5113221999409035038"));
|
|
}
|
|
}
|
|
|