=====taoyyz小陶©版权所有=====
实验三 身份证号码验证及个人信息输出。
要求:
输入身份证号码,进行三重验证,并且输出对应信息。
1、身份证验证主要包含:
1. 位数错误:正确应该为 18 位。
2. 字符错误:前面 17 个应该是数字,最后一位可以为‘X’或‘x’;
3. 校验码错误:
身份证的最后一位为校验码,校验码是用于验证前面的数字是否有错误,校
验码运算规则:
(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 的对应关系如下:
1 2 3
| 身份证号码: 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 wi : 用公式计算 2^(i-1)%11 …… 9 10 5 8 4 2 1
|
(3)求出(Σ (ai×wi))%11 之后依据下表得到效验码:
1 2
| (Σ (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)
2、个人信息输出主要包含:
1: 生日:如 1985 年 5 月 9 日。
2: 年龄:如 20 岁,应当精确到日;
3: 性别:顺序码的计数为,男性以奇数计数,女性以偶数计数
(1)编写一个身份证类,包含一个属性:身份证号;三个验证函数;一个信息输出函数。
(2)编写一个测试类,可从键盘上输入一个身份证号码,产生一个身份证对象,然后调用其相关方法对身份证号码进行验证,没有通过验证的话,提示错
误信息并让用户重新输入,如果通过验证,则输出该人的信息。
代码框架如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class CardID{ private String cardNum; public void setCardNum(String cardNum){//换一个号码 this. cardNum= cardNum; } public boolean lengthVerify(){○1 位数错误验证 } public boolean charVerify(){○2 字符错误验证 } public boolean checkcodeVerify(){○3 校验码错误验证 //测试时请将每一轮的 i,ai,wi,sum 输出,避免出错,成功后不再输出 } public void output(){○4 信息输出 //按要求输出个人信息 } } class CardIDDemo{ public static void main(String []args){ //用死循环反复测试输入、验证、输出 //注意第一步验证失败不能进入第二步,第二步失败不能进入第三步,所有验 证通过才能进行输出。 } }
|
思路:
需要两个类:Card类和CardID类
其中:1.在Card类中定义String类型的cardNum变量
2.在Card类中定义Getter/Setter方法
3.在Card类中定义3种验证方法:
3.1对于位数验证,直接判断输入的cardNum长度是否为18
3.2对于字符验证,前17位为数字,最后一位还可以为大小写的’x’
3.3对于校验码,需要取出每一位,转化为整形进行算术运算
4.在output()输出方法中,输出生日、年龄、性别
5.以上3种输出需求均在身份证号码中截取获得
6.利用Calendar类不是必须的,但是逻辑清晰,有利于日期计算
7.年龄判断不是简单的相减,需要考虑到月份和天数不够减情况下的处理
代码:
CardID类: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 174 175 176
| package com.experiment.exp3;
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Objects;
public class CardID { private String cardNum;
public void setCardNum(String cardNum) { this.cardNum = cardNum; }
public boolean lengthVerify() { if (this.cardNum.length() == 18) { return true; } else { System.out.print("位数验证错误!"); return false; } }
public boolean charVerify() { char[] chars = this.cardNum.toCharArray(); for (int i = 0; i < chars.length - 1; i++) { if (!('0' <= chars[i] && chars[i] <= '9')) { System.out.print("字符验证错误!"); return false; } } if (('0' <= chars[17] && chars[17] <= '9') || chars[17] == 'x' || chars[17] == 'X') { return true; } else { System.out.print("字符验证错误!"); return false; } }
public boolean checkCodeVerify() { String[] cardNumStr = numStringToArray(); int[] ai = new int[18]; ai[ai.length - 1] = 0; for (int i = 0; i < cardNumStr.length - 1; i++) { ai[i] = Integer.parseInt(cardNumStr[i]); } int[] wi = new int[18]; for (int i = ai.length; i > 0; i--) { wi[18 - i] = (int) Math.pow(2, (i - 1)) % 11; } int result = 0; for (int i = 0; i < ai.length; i++) { result += ai[i] * wi[i]; } int verifyCode = result % 11; String[] verifyCodeList = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; String lastChar = verifyCodeList[verifyCode]; System.out.println("身份证最后一位应该是" + "'" + lastChar + "'"); if (Objects.equals(cardNumStr[cardNumStr.length - 1].toLowerCase(), lastChar.toLowerCase())) { return true; } else { System.out.println("校验码验证错误!"); return false; } }
public void output() {
Calendar birthDate = calcBirth(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日"); String birth = sdf.format(birthDate.getTime());
String age = calcAge(birthDate);
String sex = calcSex();
System.out.println("生日:" + birth); System.out.println("年龄:" + age); System.out.println("性别:" + sex); System.out.println("==========="); }
private String calcSex() {
int numOfSex = Integer.parseInt(this.cardNum.substring(14, 17)); return numOfSex % 2 != 0 ? "男" : "女"; }
private String calcAge(Calendar birthDateString) { int yearOfBirth = birthDateString.get(Calendar.YEAR); int monthOfBirth = birthDateString.get(Calendar.MONTH) + 1; int dayOfBirth = birthDateString.get(Calendar.DATE); Calendar nowDate = Calendar.getInstance(); int yearOfNow = nowDate.get(Calendar.YEAR); int monthOfNow = nowDate.get(Calendar.MONTH) + 1; int dayOfNow = nowDate.get(Calendar.DATE); int ageOfYear = yearOfNow - yearOfBirth; int ageOfMonth = monthOfNow - monthOfBirth; if (ageOfMonth < 0) { ageOfYear--; ageOfMonth += 12; } int ageOfDay = dayOfNow - dayOfBirth; if (ageOfDay < 0) { ageOfMonth--; ageOfDay += nowDate.getActualMaximum(Calendar.DAY_OF_MONTH) + 1;
} if (ageOfMonth < 0) { ageOfYear--; ageOfMonth += 12; } return ageOfYear + "岁" + ageOfMonth + "月" + ageOfDay + "天"; }
private Calendar calcBirth() { int year = Integer.parseInt(this.cardNum.substring(6, 10)); int month = Integer.parseInt(this.cardNum.substring(10, 12)); int day = Integer.parseInt(this.cardNum.substring(12, 14)); Calendar birthDate = Calendar.getInstance(); birthDate.set(Calendar.YEAR, year); birthDate.set(Calendar.MONTH, month - 1); birthDate.set(Calendar.DATE, day); return birthDate; }
private String[] numStringToArray() { char[] chars = this.cardNum.toCharArray(); String[] numArray = new String[cardNum.length()]; for (int i = 0; i < cardNum.length(); i++) { numArray[i] = String.valueOf(chars[i]); } return numArray; } }
|
CardIDDemo类(含main方法):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
| package com.experiment.exp3;
import java.util.Scanner;
public class CardIDDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (true) { System.out.println("请输入一个身份证号:"); String cardId = sc.next(); CardID cardID = new CardID(); cardID.setCardNum(cardId); if (cardID.lengthVerify()) { if (cardID.charVerify()) { if (cardID.checkCodeVerify()) { System.out.println("验证通过"); cardID.output(); } else { error(); } } else { error(); } } else { error(); } } }
public static void error() { System.out.println("验证错误,请重新输入"); System.out.println("-----------"); } }
|
运行截图:
心得:
这个CardID类考验面向对象的综合能力,特别是成员方法,如何进行三重验证。其次就是多次用到字符串截取:String类的substring()方法
在年龄计算那一块,精确到年很简单,属于有手就行。精确到月也只是多一步判断,就是当前月份-出生月份为负数时,说明当前月份比出生月份小,那么年龄就要-1,然后修正月份,也就是月份+=12。
天数的处理跟上一步类似。要注意天数相减为负数时导致月份-1,这时候还需要再次判断月份是否为负。否则会导致原本0月,经过天数不够减之后,月份成为负1月。
感谢阅读💗