这几天碰到一个需求是实现身份证最后一位的校验,需求文档里面写了个公式,没看懂(数学早就还给老师了),于是各种查资料,发现网上的资料要么只给了说明,要么给了个固定的代码,但是写的不清不楚的,没有说明为什么要这么写,现在我就自己这几天搜集到的资料做一个简单的总结
首先mod11-2校验规则是遵循了一个国际标准,关于mod11-2校验规则的资料自行百度,这里就不做详细解释了
其次用java实现mod11-2校验规则的时候,一个特别要注意的点,就是加权因子,网上的代码大都是写死了一个数组:int[] coefficients = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2},也没个说明,鬼tmd的知道这个数组是个什么玩意儿,实际上这个是mod11-2校验规则中规定的计算加权因子的公式计算出来的结果,因为我们的身份证一般的是18位,最后一位可能是字母X,所以计算加权因子的时候,只算17位,那么这个计算公式是什么呢,其实很简单,就是2的(18-i)次方结果再对11取模的结果,就是下面的代码:
//身份证前17位每一位对应的加权因子
private static int[] weightingFactor() {
int[] weightingFactor = new int[17];
for (int i = 1; i < 18; i++) {
weightingFactor[i - 1] = (int) (Math.pow(2, 18 - i) % 11);
}
return weightingFactor;
}
有了加权因子就可以计算校验码了,校验码的生成规则:身份前17位乘以对应的加权因子然后相加,最后的总和再对11取模:
private static int getMod11CheckCode(String idCard) {
//因为weightingFactor返回的结果是固定的,所以也可以写死,这里只是为了解释这个数组是怎么生成的
// int[] coefficients = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
int[] coefficients = weightingFactor();
int sum = 0;
for (int i = 0; i < 17; i++) {
sum += (idCard.charAt(i) - '0') * coefficients[i];
}
int checkCode = sum % 11;
return checkCode;
}
最后我们准备一个数组存的是身份证号最后一位数字:static char[] checkCodes = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
这样checkCodes[getMod11CheckCode("需要校验的身份号")]如果得到的数字与身份证最后一位是相等的,那么就是校验通过了
PS:现在各大AI模型相继问世了,有的支持图片识别,大家可以用上面那个图片试试