【设计思路】
- 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
;
【代码实现思路】
- 1、使用
Scanner工具类获取输入的字符串
;- 2、将输入的
字符串转换为字符数组
(使用toCharArray()
方法),字符类型可直接参与数学运算
;- 3、查询ASCII码表可知数字0在表中对应的编码为48,一次类推,故每个char字符需要减去48,才能代表其实际数值;
- 4、创建一个
Map集合
,用于存放计算后的余数与校验码对应的值
;- 5、根据计算出的
余数获取Map集合的校验码与输入的校验码进行对比
,可得出输入的身份证号是否合法;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* @author 二师兄想吃肉
* @version 1.0
* @date 2020/12/23 13:55
*/
public class Demo {
public static void main(String[] args) {
// 创建键盘输入对象
Scanner sc = new Scanner(System.in);
System.out.println("---请输入前18位身份证号码---");
// 获取键盘输入的值
String idNo = sc.next();
// 将输入的字符串转换为字符数组,方便计算
char[] chars = idNo.toCharArray();
// 将字符数组每个字符减去 48 为真实数值(可查阅ASCII表)
int sum =
(chars[0] - 48 ) * 7 +
(chars[1] - 48 ) * 9 +
(chars[2] - 48 ) * 10 +
(chars[3] - 48 ) * 5 +
(chars[4] - 48 ) * 8 +
(chars[5] - 48 ) * 4 +
(chars[6] - 48 ) * 2 +
(chars[7] - 48 ) * 1 +
(chars[8] - 48 ) * 6 +
(chars[9] - 48 ) * 3 +
(chars[10] - 48 ) * 7 +
(chars[11] - 48 ) * 9 +
(chars[12] - 48 ) * 10 +
(chars[13] - 48 ) * 5 +
(chars[14] - 48 ) * 8 +
(chars[15] - 48 ) * 4 +
(chars[16] - 48 ) * 2;
// 取模运算
int mod = sum % 11;
// 采用键值对的形式存储余数与校验码的对应关系
Map<Integer,Character> map = new HashMap<>(11);
map.put(0,'1');
map.put(1,'0');
map.put(2,'X');
map.put(3,'9');
map.put(4,'8');
map.put(5,'7');
map.put(6,'6');
map.put(7,'5');
map.put(8,'4');
map.put(9,'3');
map.put(10,'2');
// 根据计算出的余数获取到校验码
Character character = map.get(mod);
// 将输入的校验码与获取到的校验码进行比较
if (chars[17] == character) {
System.out.println("身份证号码正确!");
} else {
System.out.println("身份证号码错误!");
System.out.println("最后一位校验码应为:" + character);
}
}
}
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author 二师兄想吃肉
* @version 1.0
* @Title: 身份证校验码
* @Description: 校验身份证号码和生成身份证校验码
* @date 2020/12/17 11:55
*/
public class Demo01 {
public static void main(String[] args) throws Exception {
randomMethod();
}
/**
* 随机执行校验身份证号码方法、生成身份证校验码方法、打印矩形
* @throws Exception
*/
public static void randomMethod() throws Exception{
while(true){
int i = new Random().nextInt(15);
if(i % 3 == 0){
checkIdNo();
}else if(i % 3 == 1){
makeCheckCode();
}else if(i % 3 == 2){
System.out.println("\n---你看↓↓↓突然就想打印个矩形---");
for (int width = 0; width < 5; width++) {
for (int height = 0; height < 25; height++) {
Thread.sleep(50);
System.out.print("*");
}
System.out.println();
}
}
}
}
/**
* 校验输入的18位身份证号码输入是否正确
* @throws Exception
*/
public static void checkIdNo() throws Exception {
System.out.println();
Scanner sc = new Scanner(System.in);
System.out.println("---请输入18位身份证号码---");
if(sc.hasNext()){
String str = sc.next();
int length = str.length();
if(length == 18){
char aChar = str.charAt(17);
if((aChar < 48 || aChar > 57) && (aChar != 88 && aChar != 120)){
System.out.println("你第" + length + "位输错了。");
return;
}
Character code = map.get(checkTwo(checkOne(str)));
if(code != 'E'){
String result = code.equals(str.charAt(17)) || Character.valueOf((char)(code + 32)).equals(str.charAt(17))
? "身份证号码校验通过!" : "身份证号码校验失败,你重试吧~";
System.out.println(result);
}else{
System.out.println("输入不合法,请输入有效数据!");
}
}else if((length > 14 && length <= 17) || (length > 18 && length <= 21)){
System.out.println("你数数是不是位数不对,我还不能告诉你校验码~");
}else if("我是憨憨".equals(str)){
System.out.println("这话说的漂亮啊弟弟");
}else {
System.out.println("能不能好好输,重来!");
}
}else{
throw new Exception("输入有误,请重新输入!");
}
}
/**
* 根据前17位身份证号码,生成最后一位校验码
*/
public static void makeCheckCode() throws Exception {
System.out.println();
Scanner sc = new Scanner(System.in);
System.out.println("---请输入前17位身份证号码---");
if(sc.hasNext()) {
String str = sc.next();
int length = str.length();
if(length == 17){
char[] chars = checkOne(str);
int i = checkTwo(chars);
Character code = map.get(i);
if(code != 'E'){
System.out.println("最后一位校验码为:" + code + "\n"
+ "18位身份证号码为:" + (str + code));
}else{
System.out.println("输入不合法,请输入有效数据!");
}
}else if((length > 13 && length <= 16) || (length > 17 && length <= 20)){
System.out.println("内容对不对我不知道,但是你输得位数不太对~");
}else if("我是憨憨".equals(str)){
System.out.println("这话说的漂亮啊弟弟");
}else {
System.out.println("能不能好好输,重来!");
}
}else{
throw new Exception("输入有误,请重新输入!");
}
}
/**
* 判断输入的身份证号长度与字符输入是否正确
* @param idNo
* @return 字符数组
* @throws Exception
*/
public static char[] checkOne(String idNo) throws Exception {
//如果参数字符串长度小于17,直接返回空字符数组,避免接下来字符串转换字符数组出现异常
//如果参数字符串长度大于18,直接返回空字符数组,属于不合法输入
if(idNo.length() < 17 || idNo.length() > 18){
return new char[]{};
}
//字符串转为字符数组
char[] chars = idNo.substring(0,17).toCharArray();
//首先判断字符串长度是否符合规则
if(chars.length == 17){
//判断每个字符是否符合规则
int num = 0;
for (int i = 0; i < chars.length; i++) {
int aChar = chars[i] += 0;
if(i < 17 && (aChar < 48 || aChar > 57)){
// throw new Exception("你第" + (i + 1) + "位输错了,你得按规矩来。");
System.out.println("你第" + (i + 1) + "位输错了,你得按规矩来。");
num++;
}
}
//如果身份证号输入字符存在不合法字符,返回空字符数组。
if (num != 0) {
return new char[]{};
}
return chars;
}else{
System.out.println("你长度不对劲,你得重新输一遍。");
return new char[]{};
}
}
/**
* 根据输入的前17位身份证号码生成最后一位校验码
* @param chars
* @return map的键
* @throws Exception
*/
public static int checkTwo(char[] chars) throws Exception{
// 将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
// 将这17位数字和系数相乘的结果相加;
if(chars.length == 17){
int sum =
(chars[0] - 48 ) * 7 +
(chars[1] - 48 ) * 9 +
(chars[2] - 48 ) * 10 +
(chars[3] - 48 ) * 5 +
(chars[4] - 48 ) * 8 +
(chars[5] - 48 ) * 4 +
(chars[6] - 48 ) * 2 +
(chars[7] - 48 ) * 1 +
(chars[8] - 48 ) * 6 +
(chars[9] - 48 ) * 3 +
(chars[10] - 48 ) * 7 +
(chars[11] - 48 ) * 9 +
(chars[12] - 48 ) * 10 +
(chars[13] - 48 ) * 5 +
(chars[14] - 48 ) * 8 +
(chars[15] - 48 ) * 4 +
(chars[16] - 48 ) * 2;
// 用加出来和除以11,看余数是多少;
int mod = sum % 11;
return mod;
}
return -1;
}
//用于存放校验码的键值map
static Map<Integer,Character> map;
//类初始化时向map集合添加数据
static {
//余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2
//尖括号添加泛型保证一定的向下兼容性
map = new ConcurrentHashMap</*Integer,Character*/>(11);
map.put(0,'1');
map.put(1,'0');
map.put(2,'X');
map.put(3,'9');
map.put(4,'8');
map.put(5,'7');
map.put(6,'6');
map.put(7,'5');
map.put(8,'4');
map.put(9,'3');
map.put(10,'2');
//作为异常处理的错误码
map.put(-1,'E');
}
}