需求:
验证身份证号码是否正确(带校验算法)
源码:
package javaCoreTech1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
*
* @author PDH
* 华师大中国大学Mooc Java核心技术编程作业
*
*/
/*验证身份证号码是否正确(带校验算法)
题目内容:
输入一个字符串,请判断是否满足身份证基本要求,并返回具体的生日yyyy-mm-dd。
如果输入数据有误,请输出0000-00-00。
基本要求是:a)必须是18位;b) 前面位数必须是数字,最后一位可以是数字或小写字母;c) 日期是存在的;d)最后一位校验码检查。
校验码规则如下:
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-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X-9-8-7-6-5-4-3-2。
5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是10,身份证的最后一位号码就是罗马数字x。
输入格式:
一个身份证号,18位
输出格式:
yyyy-mm-dd
输入样例:
53010219200508011x
输出样例:
1920-05-08
时间限制:500ms内存限制:32000kb
*/
public class P9_IDChecker {
public static void main(String[] args)
{
String id;
int checkResult = 0;
//创建一个IDChecker类
IDChecker2 idc = new IDChecker2();
do {
//输入身份证号
id = idc.enterID();
//验证身份证号
checkResult = idc.checkID(id);
switch (checkResult) {
case -1, -2, -3, -4:
System.out.println("0000-00-00");
System.out.println("请重新输入!");
break;
case 1:
System.out.println("身份证号符合当前所有校验规则!");
System.out.println("出生日期:"+id.substring(6, 10)+"-"+id.substring(10, 12)+"-"+id.substring(12, 14));
break;
default:
break;
}
}
while (checkResult!=1);
}
}
class IDChecker2{
private String id;
public IDChecker2() {
}
public String enterID() {
System.out.println("请输入身份证号:");
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
try {
id = input.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return id;
}
public int checkID(String id) {
//a)必须是18位
int lc = lengthCheck(id);
if (lc < 0) return lc;
//b) 前面位数必须是数字,最后一位可以是数字或小写字母;
int dic = digitCheck(id);
if (dic < 0) return dic;
//c) 日期是存在的。
int dac = dateCheck(id);
if (dac <0) return dac;
//d)最后一位校验码检查。
int ldc = lastDigitCheck(id);
if (ldc < 0) return ldc;
//所有校验通过后,返回1
return 1;
}
public int lengthCheck(String id) {
//a)必须是18位
if (id.length()!=18) {
System.out.println("输入错误:位数不是18位!");
return -1;
}
return 0;
}
public int digitCheck(String id) {
//b) 前面位数必须是数字,最后一位可以是数字或小写字母;
int i,n=0;
for( i=0;i<17;i++)
{
if(id.charAt(i)>='0'&&id.charAt(i)<='9')
{
n++;
}
else
break;
}
if(n<=16||!((id.charAt(17)>='0'&& id.charAt(17)<='9')||(id.charAt(17)>='a'&& id.charAt(17)<='z'))) {
System.out.println("输入错误:前面位数必须是数字,最后一位可以是数字或小写字母!");
return -2;
}
return 0;
}
public int dateCheck(String id) {
//c) 日期是存在的。
int year,month,day;
year=Integer.valueOf(id.substring(6, 10));
month=Integer.valueOf(id.substring(10, 12));
day=Integer.valueOf(id.substring(12, 14));
String strDate = id.substring(6, 14);
// 准备第一个模板,从字符串中提取出日期数字
String pat1 = "yyyyMMdd" ;
// 准备第二个模板,将提取后的日期数字变为指定的格式
String pat2 = "yyyy-MM-dd" ;
SimpleDateFormat sdf1 = new SimpleDateFormat(pat1) ; // 实例化模板对象
SimpleDateFormat sdf2 = new SimpleDateFormat(pat2) ; // 实例化模板对象
Date d = null ;
try{
d = sdf1.parse(strDate) ; // 将给定的字符串中的日期提取出来
}catch(Exception e){ // 如果提供的字符串格式有错误,则进行异常处理
e.printStackTrace() ; // 打印异常信息
}
String r=sdf1.format(d);
if(!r.equals(strDate)) {
System.out.println("输入错误:无效的出生日期!");
return -3;
}
// else
// System.out.println(sdf2.format(d)) ; // 将日期变为新的格式
//
return 0;
}
public int lastDigitCheck(String id) {
//d)最后一位校验码检查。
/*
* 校验码规则如下:
* 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-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X-9-8-7-6-5-4-3-2。
* 5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是10,身份证的最后一位号码就是罗马数字x。
*/
//1.系数数组定义
int[] factors = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
//2.求和
int sum = 0;
for (int i =0;i<17;i++) {
sum += (id.charAt(i)-'0')*factors[i];
}
//3.取余
int remainder = sum % 11;
//4.余数映射数组定义
char[] mappedDigits = {'1','0','X','9','8','7','6','5','4','3','2'};
//5.生成最后一位(校验位)
char lastDigit = mappedDigits[remainder];
// System.out.println("校验位:"+lastDigit);
//判断输入的最后一位是否符合校验规则
if (id.charAt(17)!=lastDigit) {
System.out.println("输入错误:最后一位不符合校验规则");
return -4;
}
return 0;
}
}
运行结果:
请输入身份证号:
64222420230217661
输入错误:位数不是18位!
0000-00-00
请重新输入!
请输入身份证号:
输入错误:前面位数必须是数字,最后一位可以是数字或小写字母!
0000-00-00
请重新输入!
请输入身份证号:
输入错误:无效的出生日期!
0000-00-00
请重新输入!
请输入身份证号:
642224202302176616
输入错误:最后一位不符合校验规则
0000-00-00
请重新输入!
请输入身份证号:
身份证号符合当前所有校验规则!
出生日期:2023-02-17