身份证号码共有18位,其中前6位表示所在地,第 7~14 位数字对应:出生年、月、日,第 15~16 位数字对应:所在地的派出所的代码,第 17 位数字对应性别:奇数表示男性,偶数表示女性,第 18 位数字是校检码:校检码可以是 0~9 的数字,也可以是罗马数字 X(表示10)。
2.如果已经知道一个人的身份证前17位,可以通过如下步骤得到第18位:
(1)将前面的身份证号码17位数分别乘以不同的系数,从第一位到第十七位的系数分别为:【7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2】。
(2)将这17位数字和系数相乘的结果相加。
(3)用相加结果除以11,得出余数。
(4)余数只可能有0~10这11个数字。其分别对应的最后一位身份证的号码为【1,0,10,9,8,7,6,5,4,3,2】,这就是身份证号码的校验位即最后一位。
通过以上条件,可以对一个身份证号码进行一个有效性的检测,简单实现其功能的代码及注释如下
package cn.zheng;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;
public class IdCardTest {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
while (true) {
// 创建扫描器对象
Scanner scanner = new Scanner(System.in);
// 输出提示信息
System.out.println("请输入您的身份证号码:");
// 通过扫描器获取控制台输入的字符串
String next = scanner.next();
// 判断字符串是否为有效的身份证号
if (isValidate(next)) {
System.out.println("此身份证号有效,是否继续判断:y(继续)");
if(!scanner.next().equalsIgnoreCase("y")){
break;
} else {
continue;
}
} else {
System.out.println("此身份证号无效,请重新输入");
}
}
});
thread.start();
}
/**
* 判断身份证号是否有效
*
* @param id 身份证号
* @return 表示身份证号是否有效的布尔值
*/
static boolean isValidate(String id) {
// 是否为18位,不是则返回false
if (id.length() != 18) {
System.out.println("请输入18位身份证号码");
return false;
}
// 获取前17位字符串
String id17 = id.substring(0, 17);
if (!id17.matches("[0-9]+")) {
System.out.println("前17位号码必须是数字");
return false;
}
// 获取其中日期字符串
String dateStr = id.substring(6,14);
if (!checkDate(dateStr)) {
System.out.println("身份证号中日期错误");
return false;
}
// 获取最后1位字符串
String last = id.substring(17);
// 判断最后1位校验位是否符合
if (lastNumber(id17) == -1) {
return false;
} else if (!(lastNumber(id17) == 10 && last.equalsIgnoreCase("x"))) {
// 最后1位为10,且输入的为"x"
return false;
} else if(lastNumber(id17) != Integer.parseInt(last)){
return false;
}
return true;
}
// 通过前17位计算最后一位校验位的方法
static int lastNumber(String id17) {
// 初始化求和数为0
int sum = 0;
// 判断参数长度是否不是17位
if (id17.length() != 17) {
return -1;
}
// 遍历获取前17位数字字符串,转为整型,赋值到array数组中,顺序一一对应
int[] array = new int[17];
for (int i = 0; i < array.length; i++) {
String s = String.valueOf(id17.toCharArray()[i]);
array[i] = Integer.parseInt(s);
}
// 被乘数组成的整形数组
int[] v = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
// array数组元素与被乘数数组元素一一相乘,乘积求和,赋值给sum
for (int i = 0; i < 17; i++) {
sum += array[i] * v[i];
}
// sum求余11赋值给mod,mod值(0-11)
int mod = sum % 11;
// 校验码数组
int[] check = {1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2};
// 最后一位为校验码数组中mod为索引的值(值为10时,x表示)
return check[mod];
}
// 检测身份证中日期的输入是否正确
static boolean checkDate(String dateStr){
boolean flag = true;
if (dateStr.length() == 8) {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
try {
// 设置宽松检测日期格式为false,即严格检测日期
format.setLenient(false);
format.parse(dateStr);
} catch (ParseException e) {
flag = false;
}
} else {
flag = false;
}
return flag;
}
}
控制台输入演示:
