Java 正则表达式验证身份证号
身份证号验证是常见的表单校验需求,下面我将介绍如何使用Java正则表达式来验证中国大陆的身份证号。
中国大陆身份证号规则
中国大陆的身份证号分为18位和15位两种:
-
18位身份证号:
- 前6位:地区码
- 接下来8位:出生日期(格式:YYYYMMDD)
- 接下来3位:顺序码(奇数为男性,偶数为女性)
- 最后1位:校验码(可能是数字或X)
-
15位身份证号(已逐步淘汰):
- 前6位:地区码
- 接下来6位:出生日期(格式:YYMMDD,年份是2位)
- 接下来3位:顺序码
Java正则表达式实现
验证18位身份证号
import java.util.regex.Pattern;
public class IDCardValidator {
// 18位身份证正则表达式
private static final Pattern ID_CARD_18_REGEX = Pattern.compile(
"^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$"
);
// 校验码对应值
private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
private static final char[] CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
/**
* 验证18位身份证号
* @param idCard 身份证号
* @return 是否有效
*/
public static boolean isValid18IdCard(String idCard) {
if (!ID_CARD_18_REGEX.matcher(idCard).matches()) {
return false;
}
// 验证校验码
int sum = 0;
for (int i = 0; i < 17; i++) {
sum += (idCard.charAt(i) - '0') * WEIGHT[i];
}
char checkCode = CHECK_CODE[sum % 11];
return Character.toUpperCase(idCard.charAt(17)) == checkCode;
}
public static void main(String[] args) {
String testIdCard = "11010519491231002X"; // 示例身份证号
System.out.println(isValid18IdCard(testIdCard)); // 输出: true
}
}
验证15位身份证号
import java.util.regex.Pattern;
public class IDCardValidator {
// 15位身份证正则表达式
private static final Pattern ID_CARD_15_REGEX = Pattern.compile(
"^[1-9]\\d{5}\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}$"
);
/**
* 验证15位身份证号
* @param idCard 身份证号
* @return 是否有效
*/
public static boolean isValid15IdCard(String idCard) {
return ID_CARD_15_REGEX.matcher(idCard).matches();
}
public static void main(String[] args) {
String testIdCard = "110105491231002"; // 示例15位身份证号
System.out.println(isValid15IdCard(testIdCard)); // 输出: true
}
}
综合验证(同时支持15位和18位)
import java.util.regex.Pattern;
public class IDCardValidator {
// 18位身份证正则表达式
private static final Pattern ID_CARD_18_REGEX = Pattern.compile(
"^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$"
);
// 15位身份证正则表达式
private static final Pattern ID_CARD_15_REGEX = Pattern.compile(
"^[1-9]\\d{5}\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}$"
);
// 校验码对应值
private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
private static final char[] CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
/**
* 验证身份证号(支持15位和18位)
* @param idCard 身份证号
* @return 是否有效
*/
public static boolean isValidIdCard(String idCard) {
if (idCard == null || idCard.length() != 15 && idCard.length() != 18) {
return false;
}
if (idCard.length() == 18) {
return isValid18IdCard(idCard);
} else {
return isValid15IdCard(idCard);
}
}
/**
* 验证18位身份证号
*/
private static boolean isValid18IdCard(String idCard) {
if (!ID_CARD_18_REGEX.matcher(idCard).matches()) {
return false;
}
// 验证校验码
int sum = 0;
for (int i = 0; i < 17; i++) {
sum += (idCard.charAt(i) - '0') * WEIGHT[i];
}
char checkCode = CHECK_CODE[sum % 11];
return Character.toUpperCase(idCard.charAt(17)) == checkCode;
}
/**
* 验证15位身份证号
*/
private static boolean isValid15IdCard(String idCard) {
return ID_CARD_15_REGEX.matcher(idCard).matches();
}
public static void main(String[] args) {
String testIdCard18 = "11010519491231002X"; // 示例18位身份证号
String testIdCard15 = "110105491231002"; // 示例15位身份证号
System.out.println(isValidIdCard(testIdCard18)); // 输出: true
System.out.println(isValidIdCard(testIdCard15)); // 输出: true
}
}
注意事项
- 15位身份证号已逐步淘汰,建议优先验证18位身份证号
- 正则表达式只能验证格式,不能验证身份证号的真实性
- 对于18位身份证号,我们额外实现了校验码验证,这是GB 11643-1999标准的要求
- 实际应用中,可能还需要考虑地区码的有效性验证
更严格的验证(可选)
如果需要更严格的验证,可以:
- 验证地区码是否有效(需要维护地区码列表)
- 验证出生日期是否合理(不能是未来日期)
- 验证顺序码是否符合规则
代码提供了基本的身份证号验证功能,可以根据实际需求进行调整和扩展。
