banner
NEWS LETTER

实验三 身份证号码的分析

Scroll down

实验三 身份证号码的分析

3.2 实验内容及要求

身份证号码验证及个人信息输出。在网页、管理信息系统中,我们经常会要求用户输入身份证号码,由于身份证号码较长,经常容易产生录入错误,本验证可以有效防止用户录用错误。其实身份证中还包含了用户的个人信息,包含出生地、生日、性别的等内容

如:51 01 03 19XX 01 03 028 X 为:省 市 区 出生年 月 日 顺序码 校验码

  1. 身份证验证主要包含:
  • 位数错误:正确应该为 18 位。
  • 字符错误:前面 17 个应该是数字,最后一位可以为‘X’或‘x’;
  • 校验码错误:身份证的最后一位为校验码,校验码是用于验证前面的数字是否有错误,校验码运算规则:

(1)先将最后一位设定为 0。
(2)效验码的计算公式为:(Σ (ai×wi))%11

  • 其中:i 是从右向左的包括效验码在内的序号(1-18)
  • ai 是第 i 位的数字
  • wi 是第 i 位上的加权因子,其数值依据公式 wi=(2(i-1))%11,(计算 ab:函数为java.lang.Math.pow(a,b))
  • i,ai,wi 的对应关系如下:
证号码: 5 1 0 1 0 1 1 9 8 8 0 8 0 8 0 1 2 0
i: 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
ai: 5 1 0 1 0 1 1 9 8 8 0 8 0 8 0 1 2 0
wi: 用公式计算 2^(i-1)%11 …… 9 10 5 8 4 2 1

(3)求出(Σ (ai×wi))%11 之后依据下表得到效验码:

(Σ (ai×wi))%11 0 1 2 3 4 5 6 7 8 9 10
效验码值 1 0 X 9 8 7 6 5 4 3 2

(4)计算 ab:函数为:java.lang.Math.pow(a,b)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
要求: 
1)编写一个身份证类,包含一个属性:身份证号;三个验证函数;一个
信息输出函数。
2)编写一个测试类,可从键盘上输入一个身份证号码,产生一个身份证
对象,然后调用其相关方法对身份证号码进行验证,没有通过验证的话,提示错
误信息并让用户重新输入,如果通过验证,则输出该人的信息。
代码框架如下:
class CardID{
private String cardNum;
public void setCardNum(String cardNum){//换一个号码
this. cardNum= cardNum; }
1 位数错误验证
public boolean lengthVerify(){
}
2 字符错误验证
public boolean charVerify(){
}
3 校验码错误验证
public boolean checkcodeVerify(){
//测试时请将每一轮的 i,ai,wi,sum 输出,避免出错,成功后不再输出
}
4 信息输出
public void output(){
//按要求输出个人信息
}
}
class CardIDDemo{
public static void main(String []args){
//用死循环反复测试输入、验证、输出
//注意第一步验证失败不能进入第二步,第二步失败不能进入第三步,所有验证通过才能进行输出。
}
}

Card类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
* @author by LiuKui
* @date 2021/3/3.
*/
public class CardID {

private String cardNum;
public int Y;
public int birDay, birYear, birMonth, dif, sex, day, month, year; //出生日 年 月,年龄,性别,现在日 月 年
public String curr;
public boolean z;

public void setCardNum(String cardNum) {//换一个号码
this.cardNum = cardNum;
}

public boolean lengthVerify() {//1 位数错误验证
return this.cardNum.length() == 18;
}

public boolean charVerify() {//2 字符错误验证
boolean A = true;
char[] Arr = cardNum.toCharArray();//转化成字符数组
//判断是否是数字
for (int i = 0; i < cardNum.length(); i++) {
if (Arr[i] - '0' < 0 || Arr[i] - '0' > 9) {
A = false;
break;
}
}
//判断最后一维是否是X或x
if (Arr[cardNum.length() - 1] == 'x' || Arr[cardNum.length() - 1] == 'X') {
A = true;
}
return A;
}

public boolean checkCodeVerify() {//3 校验码错误验证
// 测试时请将每一轮的 i,ai,wi,sum 输出,避免出错,成功后不再输出
String testNum = this.cardNum.substring(0, 17) + "0";//提取字符串中介于两个指定下标之间的字符
int i, ai, wi, sum = 0;
for (i = 18; i >= 1; i--) {
ai = testNum.charAt(18 - i) - 48;
wi = (int) Math.pow(2, i - 1) % 11;
sum += ai * wi;
}
int mod = sum % 11;
char[] last = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
System.out.println("正确的校验码为:" + last[mod]);
return this.cardNum.toUpperCase().charAt(17) == last[mod];
}

public void output() {//4 信息输出
//按要求输出个人信息
birYear = Integer.parseInt(cardNum.substring(6, 10));
birDay = Integer.parseInt(cardNum.substring(12, 14));
birMonth = Integer.parseInt(cardNum.substring(10, 12));
dif = Y - birYear;
sex = Integer.parseInt(cardNum.substring(16, 17));

Date crr = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
curr = sdf.format(crr);
String[] D = curr.split("-");
year = Integer.parseInt(D[0]);
day = Integer.parseInt(D[2]);
month = Integer.parseInt(D[1]);
dif = year - birYear;
if (month == birMonth && day < birDay) {
dif--;
}
if (month < birMonth) {
dif--;
}

System.out.println("出生日期为:" + birYear + "年" + birMonth + "月" + String.format("%02d", birDay) + "日");

//出生日期字符串“1998-05-22”
String bornData = cardNum.substring(6, 10) + "-" + cardNum.substring(10, 12) + "-" + cardNum.substring(12, 14);
// //计算时间天数
// String bornTime;

// //月按30天算
// System.out.println("你的年龄为:" + dif + "岁" + bornTime % 365 / 30 + "月" + bornTime % 365 % 30 + "天");
try {
System.out.println("你的年龄为:" + calTimeAgo(sdf.parse(bornData)));
} catch (ParseException e) {
e.printStackTrace();
}
if (sex % 2 == 1) {
System.out.println("性别:男");
} else {
System.out.println("性别:女");
}

}

public static String calTimeAgo(Date date) {
Date nowDate = new Date();
// if (date.after(nowDate)) {
// return "0分钟前";
// }
//初始化calendar对象
Calendar nowCal = Calendar.getInstance();
Calendar dateCal = Calendar.getInstance();
//获取当前和出生时间
nowCal.setTime(nowDate);
dateCal.setTime(date);

//年龄
int yearAgo = nowCal.get(Calendar.YEAR) - dateCal.get(Calendar.YEAR);
//计算相差月份
int monthAgo = nowCal.get(Calendar.MONTH) - dateCal.get(Calendar.MONTH);

if (monthAgo < 0) {
yearAgo--;
monthAgo += 12;
}
int dayAgo = nowCal.get(Calendar.DAY_OF_MONTH) - dateCal.get(Calendar.DAY_OF_MONTH);
if (dayAgo < 0) {
monthAgo--;
//获取当年某个月最大天数
dayAgo += dateCal.getActualMaximum(Calendar.DAY_OF_MONTH);
if (monthAgo < 0) {
yearAgo--;
monthAgo += 12;
}
}
if ( dayAgo == 1) {
return (yearAgo < 1 ? "" : (yearAgo + "岁"))
+ (monthAgo < 1 ? "" : (monthAgo + "月")) +
(dayAgo < 1 ? "" : (dayAgo + "天")) + "\t" + "昨天过生!";
}
if (dayAgo == 0) {
return (yearAgo < 1 ? "" : (yearAgo + "岁"))
+ (monthAgo < 1 ? "" : (monthAgo + "月")) +
(dayAgo < 1 ? "" : (dayAgo + "天")) + "\t" + "今天过生!";
}
return (yearAgo < 1 ? "" : (yearAgo + "岁"))
+ (monthAgo < 1 ? "" : (monthAgo + "月")) +
(dayAgo < 1 ? "" : (dayAgo + "天"))+ "\t" + "还没过生!";
}


//通过天数计算
// public static long calTimeAgo(String bornData) {
// SimpleDateFormat s = new SimpleDateFormat("yyy-MM-dd");//字符串转换成date类型
// Date d = null;
// //异常处理
// try {
// d = s.parse(bornData);
// } catch (ParseException e) {
// e.printStackTrace();
// }
//
// Date now = new Date();//获取当前时间
// long nowTime = now.getTime();//将当前date时间转换成毫秒
// long bornTime = d.getTime();//将出生日期转换成毫秒
// long time = nowTime - bornTime;//当前时间的毫秒减掉出生时间的毫秒就是活了多久的毫秒数
// //根据毫秒判断出生与否,出生了就将毫秒时间转换成天数,一秒=一千毫秒,一分钟有60秒,一小时60分,一天24小时
// return time / 1000 / 60 / 60 / 24;
// }


}

CardDemo测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.text.ParseException;
import java.util.Scanner;

/**
* @author by LiuKui
* @date 2021/3/3.
*/

public class CardIDDemo {
public static void main(String[] args) throws ParseException {
//用死循环反复测试输入、验证、输出
//注意第一步验证失败不能进入第二步,第二步失败不能进入第三步,所有验证通过才能进行输出。
CardID t = new CardID();
String id = " ";
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("请输入需要验证的身份证号:");
id = sc.nextLine();
t.setCardNum(id);

if (!t.lengthVerify()) {
System.out.println("长度有错!请重新输入。");
} else if (!t.charVerify()) {
System.out.println("输入非数字字符!请重新输入。");
} else if (!t.checkCodeVerify()) {
System.out.println("最后一位验证码错误!请重新输入。");
} else {
t.output();
}
}

}

}


运行结果:

4

原文章链接:https://blog.csdn.net/qq_45441117/article/details/111336186

其他文章
目录导航 置顶
  1. 1. 实验三 身份证号码的分析
    1. 1.1. 3.2 实验内容及要求
      1. 1.1.1. 身份证号码验证及个人信息输出。在网页、管理信息系统中,我们经常会要求用户输入身份证号码,由于身份证号码较长,经常容易产生录入错误,本验证可以有效防止用户录用错误。其实身份证中还包含了用户的个人信息,包含出生地、生日、性别的等内容
      2. 1.1.2. 如:51 01 03 19XX 01 03 028 X 为:省 市 区 出生年 月 日 顺序码 校验码
      3. 1.1.3. Card类
      4. 1.1.4. CardDemo测试类
      5. 1.1.5. 运行结果:
  2. 2. 运行结果:
    1. 2.0.1. 原文章链接:https://blog.csdn.net/qq_45441117/article/details/111336186