用Java写一段中国身份证的正则表达式,要求验证身份证中的日期,且大于1900年,以及校验码验证

发布时间 2023-04-11 09:13:07作者: 根号三先生
以下是一个Java正则表达式,可用于验证中国身份证中的日期,并要求日期在1900年及之后:
String regex = "(?:(?:19[0-9]\\d)|(?:[2-9]\\d{3}))(?:0[1-9]|1[012])(?:0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]";

这个正则表达式的含义如下:

  • (?:(?:19[0-9]\\d)|(?:[2-9]\\d{3})): 匹配1900年及之后的年份,其中(?:19[0-9]\\d)匹配1900年到1999年,(?:[2-9]\\d{3})匹配2000年及之后的年份。
  • (?:0[1-9]|1[012]): 匹配月份,允许的值为01到12。
  • (?:0[1-9]|[12]\\d|3[01]): 匹配日期,允许的值为01到31。
  • \\d{3}: 匹配身份证号码中的顺序码,由三位数字组成。
  • [\\dXx]: 匹配身份证号码中的校验码,可以是数字0到9或者字母X或x。

注意:这个正则表达式只验证了日期部分,对于身份证号码的其他部分(如地区码、性别等),还需要结合其他规则进行验证。


身份证号码中最后一位校验码的计算方法是通过前面17位数字的加权和来得到的,具体步骤如下:
  1. 将身份证号码前17位数字分别乘以对应的权重因子,权重因子从左至右依次为:7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2。
  2. 将这17个乘积相加得到一个总和。
  3. 将这个总和除以11,得到的余数可以对应一个数字,余数为0时校验码为1,余数为1时校验码为0,余数为2时校验码为X(大写),余数为3到10时校验码为11减去余数。

例如,对于身份证号码为11010119900307572X的校验码的计算方法如下:

  1. 分别乘以权重因子得到:1x7 + 1x9 + 0x10 + 1x5 + 0x8 + 1x4 + 1x2 + 9x1 + 9x6 + 0x3 + 3x7 + 0x9 + 7x10 + 5x5 + 2x8 + 1x4 + 0x2 = 197
  2. 将这个总和除以11得到余数2。
  3. 根据余数2可以对应一个校验码X,因此该身份证号码的完整校验码为X。

在Java中,可以通过以下代码来实现身份证号码校验码的验证:

/**
 * 验证身份证号码的校验码是否正确
 *
 * @param idCardNumber 身份证号码
 * @return 校验结果,true表示校验通过,false表示校验失败
 */
public static boolean verifyIdCardCheckCode(String idCardNumber) {
    // 身份证号码长度必须为18位
    if (idCardNumber.length() != 18) {
        return false;
    }

    // 校验码只可能是0~9或X(大写)
    char lastChar = idCardNumber.charAt(17);
    if (!Character.isDigit(lastChar) && lastChar != 'X') {
        return false;
    }

    // 计算校验码
    int sum = 0;
    for (int i = 0; i < 17; i++) {
        char c = idCardNumber.charAt(i);
        if (!Character.isDigit(c)) {
            return false;
        }
        int digit = c - '0';
        int weight = WEIGHT_FACTOR[i];
        sum += digit * weight;
    }
    int remainder = sum % 11;
    char expectedCheckCode = CHECK_CODE[remainder];

    // 检查校验码是否一致
    return expectedCheckCode == lastChar;
}

// 权重因子数组
private static final int[] WEIGHT_FACTOR = {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'};

在上面的代码中,我们使用一个静态的WEIGHT_FACTOR数组来存储身份证号码前17位数字对应的权重因子,以及一个静态的CHECK_CODE数组来存储11种可能的校验码。在verifyIdCardCheckCode方法中,我们首先检查输入的身份证号码长度和校验码是否符合要求,然后依次计算前17位数字的加权和,并根据计算出的余数查找校验码,最后检查计算出的校验码和输入的校验码是否一致即可。

需要注意的是,这个校验码验证的方法只是一个简单的实现,对于非法输入的身份证号码仍然可能产生错误的校验结果。如果需要更加严格的校验方法,可以考虑使用正则表达式等更加复杂的工具来实现。