package com.ruoyi.im.util;
|
|
import java.util.regex.Pattern;
|
import java.util.Calendar;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
public class ValidatorUtil {
|
|
// 手机号正则表达式(匹配中国大陆手机号)
|
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
|
|
// 身份证号正则表达式(18位)
|
private static final String ID_CARD_REGEX = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
|
|
// 省份代码映射
|
private static final Map<String, String> PROVINCE_CODES = new HashMap<>();
|
|
static {
|
// 初始化省份代码
|
PROVINCE_CODES.put("11", "北京");
|
PROVINCE_CODES.put("12", "天津");
|
PROVINCE_CODES.put("13", "河北");
|
PROVINCE_CODES.put("14", "山西");
|
PROVINCE_CODES.put("15", "内蒙古");
|
PROVINCE_CODES.put("21", "辽宁");
|
PROVINCE_CODES.put("22", "吉林");
|
PROVINCE_CODES.put("23", "黑龙江");
|
PROVINCE_CODES.put("31", "上海");
|
PROVINCE_CODES.put("32", "江苏");
|
PROVINCE_CODES.put("33", "浙江");
|
PROVINCE_CODES.put("34", "安徽");
|
PROVINCE_CODES.put("35", "福建");
|
PROVINCE_CODES.put("36", "江西");
|
PROVINCE_CODES.put("37", "山东");
|
PROVINCE_CODES.put("41", "河南");
|
PROVINCE_CODES.put("42", "湖北");
|
PROVINCE_CODES.put("43", "湖南");
|
PROVINCE_CODES.put("44", "广东");
|
PROVINCE_CODES.put("45", "广西");
|
PROVINCE_CODES.put("46", "海南");
|
PROVINCE_CODES.put("50", "重庆");
|
PROVINCE_CODES.put("51", "四川");
|
PROVINCE_CODES.put("52", "贵州");
|
PROVINCE_CODES.put("53", "云南");
|
PROVINCE_CODES.put("54", "西藏");
|
PROVINCE_CODES.put("61", "陕西");
|
PROVINCE_CODES.put("62", "甘肃");
|
PROVINCE_CODES.put("63", "青海");
|
PROVINCE_CODES.put("64", "宁夏");
|
PROVINCE_CODES.put("65", "新疆");
|
PROVINCE_CODES.put("71", "台湾");
|
PROVINCE_CODES.put("81", "香港");
|
PROVINCE_CODES.put("82", "澳门");
|
}
|
|
// 身份证校验码权重
|
private static final int[] ID_CARD_WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
|
|
// 身份证校验码对应值
|
private static final char[] ID_CARD_CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
|
|
/**
|
* 验证手机号格式
|
* @param phone 手机号码
|
* @return 是否有效
|
*/
|
public static boolean isValidPhone(String phone) {
|
if (phone == null || phone.trim().isEmpty()) {
|
return false;
|
}
|
|
// 移除可能的分隔符(如空格、短横线等)
|
String cleanedPhone = phone.replaceAll("[\\s-]+", "");
|
|
return Pattern.matches(PHONE_REGEX, cleanedPhone);
|
}
|
|
/**
|
* 验证身份证号格式
|
* @param idCard 身份证号码
|
* @return 是否有效
|
*/
|
public static boolean isValidIdCard(String idCard) {
|
if (idCard == null || idCard.trim().isEmpty()) {
|
return false;
|
}
|
|
// 转换为大写以便统一处理
|
String cleanedIdCard = idCard.trim().toUpperCase();
|
|
// 基本格式校验
|
if (!Pattern.matches(ID_CARD_REGEX, cleanedIdCard)) {
|
return false;
|
}
|
|
// 校验省份代码
|
String provinceCode = cleanedIdCard.substring(0, 2);
|
if (!PROVINCE_CODES.containsKey(provinceCode)) {
|
return false;
|
}
|
|
// 校验生日日期
|
if (!isValidBirthday(cleanedIdCard.substring(6, 14))) {
|
return false;
|
}
|
|
// 校验校验码
|
return isValidCheckCode(cleanedIdCard);
|
}
|
|
/**
|
* 验证身份证中的生日日期是否有效
|
* @param birthdayStr 生日字符串(YYYYMMDD格式)
|
* @return 是否有效
|
*/
|
private static boolean isValidBirthday(String birthdayStr) {
|
try {
|
int year = Integer.parseInt(birthdayStr.substring(0, 4));
|
int month = Integer.parseInt(birthdayStr.substring(4, 6));
|
int day = Integer.parseInt(birthdayStr.substring(6, 8));
|
|
// 检查年份范围(假设身份证持有者年龄在0-150岁之间)
|
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
if (year < currentYear - 150 || year > currentYear) {
|
return false;
|
}
|
|
// 检查月份
|
if (month < 1 || month > 12) {
|
return false;
|
}
|
|
// 检查日期
|
if (day < 1 || day > 31) {
|
return false;
|
}
|
|
// 检查特定月份的天数
|
if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {
|
return false;
|
}
|
|
// 检查闰年二月
|
if (month == 2) {
|
boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
|
if (isLeapYear && day > 29) {
|
return false;
|
}
|
if (!isLeapYear && day > 28) {
|
return false;
|
}
|
}
|
|
return true;
|
} catch (NumberFormatException e) {
|
return false;
|
}
|
}
|
|
/**
|
* 验证身份证校验码
|
* @param idCard 身份证号码
|
* @return 校验码是否正确
|
*/
|
private static boolean isValidCheckCode(String idCard) {
|
try {
|
int sum = 0;
|
for (int i = 0; i < 17; i++) {
|
int digit = Character.getNumericValue(idCard.charAt(i));
|
sum += digit * ID_CARD_WEIGHT[i];
|
}
|
|
int mod = sum % 11;
|
char checkCode = ID_CARD_CHECK_CODE[mod];
|
|
return checkCode == idCard.charAt(17);
|
} catch (Exception e) {
|
return false;
|
}
|
}
|
|
/**
|
* 测试方法
|
*/
|
public static void main(String[] args) {
|
// 测试手机号验证
|
String[] testPhones = {
|
"13800138000",
|
"12345678901",
|
"1861234567",
|
"19612345678",
|
" 138-0013-8000 ",
|
"123abc45678"
|
};
|
|
System.out.println("手机号验证测试:");
|
for (String phone : testPhones) {
|
System.out.println(phone + " : " + isValidPhone(phone));
|
}
|
|
System.out.println("\n身份证验证测试:");
|
// 测试身份证验证
|
String[] testIdCards = {
|
"11010519491231002X", // 有效身份证
|
"123456789012345678", // 无效身份证
|
"110105194902300021", // 无效日期(非闰年2月30日)
|
"110105194913310022", // 无效月份
|
"999999200001010000" // 无效省份代码
|
};
|
|
for (String idCard : testIdCards) {
|
System.out.println(idCard + " : " + isValidIdCard(idCard));
|
}
|
}
|
}
|