使用Spring Boot实现居民身份证合法性验证

使用Spring Boot实现居民身份证合法性验证

在现代社会中,身份证号码的合法性验证是很多系统中不可或缺的一部分。身份证号码用于确认个人身份,其格式和校验机制各不相同。本文将介绍如何使用Spring Boot构建一个通用控制器,通过API来验证中国大陆、台湾、澳门和香港居民的身份证号码合法性。

代码概述

本文的核心代码是一个Spring Boot控制器CommonController,它提供了一个API用于验证身份证号码的合法性。以下是该控制器的完整代码:

@SuppressWarnings("AlibabaUndefineMagicConstant")
@Tag(name = "通用控制器", description = "通用控制器")
@RestController
@RequestMapping("/common")
public class CommonController {@Autowiredprivate ICommonService commonService;/*** 每一位的权重*/private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};/*** 校验码对应表*/private static final char[] CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};/*** 正则表达式匹配澳门身份证号码*/private static final Pattern MACAU_ID_PATTERN = Pattern.compile("[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?");/*** 居民身份证合法性验证** @param idCard 身份证号码* @return ValidationResultModel*/@Operation(summary = "居民身份证合法性验证", description = "居民身份证合法性验证")@Parameter(name = "idCard", description = "居民身份证号码", required = true, in = ParameterIn.QUERY)@GetMapping("/validateID")public ApiResult<ValidationResultModel> validateIdCard(@RequestParam("idCard") String idCard) throws ParseException {IDCardType idCardType = determineIdCardType(idCard);switch (idCardType) {case MAINLAND:return validateMainlandId(idCard);case TAIWAN:return validateTaiwanId(idCard);case MACAU:return validateMacauId(idCard);case HONGKONG:return validateHongKongId(idCard);default:ValidationResultModel invalid = new ValidationResultModel();invalid.setValid(false);invalid.setMessage("身份证件号码无效,请仔细核对后重新输入!");return ApiResult.ok(invalid);}}private IDCardType determineIdCardType(String idCard) {if (idCard.matches("[1-9][0-9]{5}(19[0-9]{2}|20[0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9Xx]")) {return IDCardType.MAINLAND;} else if (idCard.matches("[A-Z][0-9]{9}")) {return IDCardType.TAIWAN;} else if (idCard.matches("[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?")) {return IDCardType.MACAU;} else if (idCard.matches("[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?")) {return IDCardType.HONGKONG;} else {return IDCardType.UNKNOWN;}}enum IDCardType {MAINLAND,TAIWAN,MACAU,HONGKONG,UNKNOWN}private static char getCheckCode(String idCard17) {int sum = 0;for (int i = 0; i < 17; i++) {sum += (idCard17.charAt(i) - '0') * WEIGHT[i];}return CHECK_CODE[sum % 11];}public boolean validateTaiwanId(String id) {if (id == null || !id.matches("[A-Z][0-9]{9}")) {return false;}char letter = id.charAt(0);int letterValue = LETTER_TO_NUMBER_MAP.get(letter);int letter1 = letterValue / 10;int letter2 = letterValue % 10;int sum = letter1 + letter2 * 9;int[] weights = {8, 7, 6, 5, 4, 3, 2, 1};for (int i = 0; i < 8; i++) {sum += Character.getNumericValue(id.charAt(i + 1)) * weights[i];}sum += Character.getNumericValue(id.charAt(9));return sum % 10 == 0;}private static final Map<Character, Integer> LETTER_TO_NUMBER_MAP = new HashMap<>();static {LETTER_TO_NUMBER_MAP.put('A', 10);LETTER_TO_NUMBER_MAP.put('B', 11);LETTER_TO_NUMBER_MAP.put('C', 12);LETTER_TO_NUMBER_MAP.put('D', 13);LETTER_TO_NUMBER_MAP.put('E', 14);LETTER_TO_NUMBER_MAP.put('F', 15);LETTER_TO_NUMBER_MAP.put('G', 16);LETTER_TO_NUMBER_MAP.put('H', 17);LETTER_TO_NUMBER_MAP.put('J', 18);LETTER_TO_NUMBER_MAP.put('K', 19);LETTER_TO_NUMBER_MAP.put('L', 20);LETTER_TO_NUMBER_MAP.put('M', 21);LETTER_TO_NUMBER_MAP.put('N', 22);LETTER_TO_NUMBER_MAP.put('P', 23);LETTER_TO_NUMBER_MAP.put('Q', 24);LETTER_TO_NUMBER_MAP.put('R', 25);LETTER_TO_NUMBER_MAP.put('S', 26);LETTER_TO_NUMBER_MAP.put('T', 27);LETTER_TO_NUMBER_MAP.put('U', 28);LETTER_TO_NUMBER_MAP.put('V', 29);LETTER_TO_NUMBER_MAP.put('W', 30);LETTER_TO_NUMBER_MAP.put('X', 31);LETTER_TO_NUMBER_MAP.put('Y', 32);LETTER_TO_NUMBER_MAP.put('Z', 33);}public static boolean validateMacauId(String id) {if (id == null || !MACAU_ID_PATTERN.matcher(id).matches()) {return false;}int[] weights = {8, 7, 6, 5, 4, 3, 2, 1};int sum = 0;for (int i = 0; i < 7; i++) {char c = id.charAt(i);sum += Character.getNumericValue(c) * weights[i];}char checkChar = id.charAt(7);int checkCode;if (checkChar == 'A') {checkCode = 10;} else {checkCode = Character.getNumericValue(checkChar);}return (sum + checkCode) % 11 == 0;}public static boolean validateHongKongId(String id) {if (id == null || !id.matches("[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?")) {return false;}id = id.replace("(", "").replace(")", "");if (id.length() == 8) {id = " " + id;}if (id.length() != 9) {return false;}int[] weights = {9, 8, 7, 6, 5, 4, 3, 2, 1};int total = 0;for (int i = 0; i < 9; i++) {total += charToValue(id.charAt(i)) * weights[i];}int remainder = total % 11;char checkDigit = id.charAt(id.length() - 1);if (remainder == 0) {return checkDigit == '0';} else if (remainder == 1) {return Character.toUpperCase(checkDigit) == 'A';} else {return checkDigit == Character.forDigit(11 - remainder, 10);}}private static int charToValue(char c) {if (c == ' ') {return 36;} else if (Character.isLetter(c)) {return Character.toUpperCase(c) - 55;} else {return Character.getNumericValue(c);}}
}

功能解析

1. 主要组件

注解
  • @Tag:用于Swagger文档生成,定义了控制器的名称和描述。
  • @RestController:表明该类是一个控制器,并且每个方法都会返回一个对象,这些对象会自动转换为JSON格式。
  • @RequestMapping:定义了基础路径为/common,即所有的请求都以该

路径为前缀。

自动注入
  • @Autowired:自动注入了一个服务接口ICommonService,用于业务逻辑的处理。

2. 常量

身份证校验相关常量
  • WEIGHT:大陆居民身份证每位数字的权重,用于校验码计算。
  • CHECK_CODE:校验码对照表,根据前17位的计算结果获取校验码。
  • MACAU_ID_PATTERN:用于匹配澳门身份证号码的正则表达式。

3. 方法

validateIdCard
  • 接收一个身份证号码,并根据其类型调用相应的校验方法。
  • 校验类型包括大陆、台湾、澳门、香港的身份证号码。
determineIdCardType
  • 根据身份证号码的格式判断其类型(大陆、台湾、澳门、香港、未知)。

4. 身份证校验方法

  • getCheckCode:计算大陆居民身份证前17位的校验码。
  • validateTaiwanId:校验台湾身份证号码是否合法。
  • validateMacauId:校验澳门身份证号码是否合法。
  • validateHongKongId:校验香港身份证号码是否合法。

详细说明

居民身份证合法性验证

大陆身份证

大陆居民身份证号码为18位数字,前17位为出生日期、地区代码等信息,第18位为校验码。校验码根据前17位数字计算得出:

private static char getCheckCode(String idCard17) {int sum = 0;for (int i = 0; i < 17; i++) {sum += (idCard17.charAt(i) - '0') * WEIGHT[i];}return CHECK_CODE[sum % 11];
}
台湾身份证

台湾身份证号码为10位,第一位为字母,表示地区,后9位为数字。校验时需要将字母转换为对应的数字,并根据特定权重计算总和:

public boolean validateTaiwanId(String id) {if (id == null || !id.matches("[A-Z][0-9]{9}")) {return false;}char letter = id.charAt(0);int letterValue = LETTER_TO_NUMBER_MAP.get(letter);int letter1 = letterValue / 10;int letter2 = letterValue % 10;int sum = letter1 + letter2 * 9;int[] weights = {8, 7, 6, 5, 4, 3, 2, 1};for (int i = 0; i < 8; i++) {sum += Character.getNumericValue(id.charAt(i + 1)) * weights[i];}sum += Character.getNumericValue(id.charAt(9));return sum % 10 == 0;
}
澳门身份证

澳门身份证号码为9位,前7位为数字,第8位为校验码。需要根据特定权重计算校验码:

public static boolean validateMacauId(String id) {if (id == null || !MACAU_ID_PATTERN.matcher(id).matches()) {return false;}int[] weights = {8, 7, 6, 5, 4, 3, 2, 1};int sum = 0;for (int i = 0; i < 7; i++) {char c = id.charAt(i);sum += Character.getNumericValue(c) * weights[i];}char checkChar = id.charAt(7);int checkCode;if (checkChar == 'A') {checkCode = 10;} else {checkCode = Character.getNumericValue(checkChar);}return (sum + checkCode) % 11 == 0;
}
香港身份证

香港身份证号码由8或9位组成,前1-2位为字母,后6位为数字,最后一位为校验码。需要根据特定权重计算校验码:

public static boolean validateHongKongId(String id) {if (id == null || !id.matches("[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?")) {return false;}id = id.replace("(", "").replace(")", "");if (id.length() == 8) {id = " " + id;}if (id.length() != 9) {return false;}int[] weights = {9, 8, 7, 6, 5, 4, 3, 2, 1};int total = 0;for (int i = 0; i < 9; i++) {total += charToValue(id.charAt(i)) * weights[i];}int remainder = total % 11;char checkDigit = id.charAt(id.length() - 1);if (remainder == 0) {return checkDigit == '0';} else if (remainder == 1) {return Character.toUpperCase(checkDigit) == 'A';} else {return checkDigit == Character.forDigit(11 - remainder, 10);}
}

总结

本文介绍了如何使用Spring Boot构建一个通用控制器,通过API来验证中国大陆、台湾、澳门和香港居民的身份证号码合法性。通过具体的代码示例,详细解释了不同地区身份证号码的校验逻辑。希望这篇文章对您在实际开发中有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/874380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

easyExcel和poi的版本对应

easypoi3.0.5对应的poi版本_easypoi和poi版本对应-CSDN博客 https://github.com/alibaba/easyexcel/blob/v3.2.0/pom.xml 解决 java.lang.NoClassDefFoundError: org/apache/poi/POIXMLTypeLoader 报错-CSDN博客 参考这个文档解决的- 引入最佳版本是3.15版本 java.lang.NoClas…

微服务:网关

网关 网关,即网络的关口,当一个网络传输到另一个网络时就需要经过网关来实现 数据的路由和转发 以及 数据安全的校验 网关技术实现 SpringCloudGateWay: 基于Spring的WebFlux技术,完全支持响应式编程,吞吐能力更强 SpringCloudGateWay 依赖 <!--网关--><depe…

【Rust光年纪】数据科学与机器学习:深入了解Rust语言中的6个关键库

Rust语言中的数据科学和机器学习&#xff1a;六大库全面解析 前言 随着Rust语言的不断发展&#xff0c;越来越多的优秀库和框架涌现出来&#xff0c;为不同领域的开发者提供了丰富的选择。本文将介绍一些适用于Rust语言的机器学习、数据处理和自然语言处理领域的优秀库和框架…

JAVA毕业设计152—基于Java+Springboot+vue+小程序的个人健康管理系统小程序(源代码+数据库+15000字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue小程序的个人健康管理系统小程序(源代码数据库15000字论文)152 一、系统介绍 本项目前后端分离带小程序(可以改为ssm版本)&#xff0c;分为用户、管理员两种…

Ubuntu下载jdk:cannot execute binary file

虚拟机上Ubuntu系统安装jdk且配置环境之后&#xff0c;java -version显示cannot execute binary file&#xff0c;多番查阅推测是由于系统和jdk版本不兼容的原因。 uname -m查看系统版本位i686&#xff0c;是32位的&#xff0c;和64位的jdk版本不兼容。因此&#xff0c;下载32位…

Postman与WebSockets:实时通信的桥梁

Postman与WebSockets&#xff1a;实时通信的桥梁 在当今的Web应用中&#xff0c;实时通信变得越来越重要。WebSockets提供了一种在单个连接上进行全双工通信的方法&#xff0c;允许服务器和客户端之间进行实时数据交换。Postman&#xff0c;作为一款强大的API开发和测试工具&a…

阻止 chrome “[保存并填写地址](chrome://settings/addresses)“ 导致输入框聚焦时出现候选项

参考 禁止浏览器自动填充到表单 的这个回答 代码 要求将不可见的input框放在页面的最前面&#xff0c;如body起始处&#xff0c; chrome之类的浏览器会填充最前面的输入框。 <!-- 阻止浏览器的自动填充 --> <input type"text" name"_prevent_auto_co…

[css3] 如何设置边框颜色渐变

div {border: 4px solid;border-image: linear-gradient(to right, #8f41e9, #578aef) 1; }参考&#xff1a; 5种CSS实现渐变色边框&#xff08;Gradient borders方法的汇总

【Python】探索 Python 中的 divmod 方法

为何每次早餐 仍然魂离魄散 原来 那朝分手都要啜泣中上班 明明能够过得这关 赢回旁人盛赞 原来 顽强自爱这样难 难得的激情总枉费 残忍的好人都美丽 别怕 你将无人会代替 &#x1f3b5; 陈慧娴《情意结》 在 Python 编程中&#xff0c;经常需要同时获取除…

如何通过smtp设置使ONLYOFFICE协作空间服务器可以发送注册邀请邮件

什么是ONLYOFFICE协作空间 ONLYOFFICE协作空间&#xff0c;是Ascensio System SIA公司出品的&#xff0c;基于Web的&#xff0c;开源的&#xff0c;跨平台的&#xff0c;在线文档编辑和协作的解决方案。在线Office包含了最基本的办公三件套&#xff1a;文档编辑器、幻灯片编辑…

FPGA实验1:简单逻辑电路

一、实验目的及要求 学习Create-SOPC实验平台的使用方法&#xff1b;熟悉Quartus II 软件平台和使用 VHDL 语言设计电路的方法&#xff1b;学习简单逻辑电路的设计、仿真和硬件测试。 二、实验原理 运用Quartus II 集成环境下的VHDL文本设计方法设计半加器&#xff0c;进行波…

LInux工具(2)

目录 1.关于底行模式的一个设置 1.1设置行号 1.2取消行号 2.简单vim配置 2.1简单认识 2.2配置选项 2.3其他说明 3.库的引入 3.1背景知识 3.2对应指令 3.3相关介绍 3.4.o文件和库的链接 3.5静态库的安装和测试 3.6动静态库对比 1.关于底行模式的一个设置 1.1设置行…

黑马点评-Postman卡住sending Requst原因解决

不知道为什么&#xff0c;用这个c1e1d5的token就会一直卡死&#xff0c;但是换了一个token就解决了&#xff0c;目前不知道为什么 解决了&#xff0c;原来是这个请求下面的函数发生了死循环&#xff01;&#xff01;太瓜皮了我超&#xff01; 把num写成了count&#xff0c;导…

函数(递归)

递归&#xff1a;程序调用自身编程技巧称为递归。 在学习递归前需要粗略的了解一下内存&#xff0c;内存分为三类&#xff0c;分别是栈区、堆区和静态区。对于栈区来说&#xff0c;每调用一次函数都会为本次函数开辟一块空间&#xff0c;然而栈区也是有空间限制的&#xff0c;随…

Golang | Leetcode Golang题解之第242题有效的字母异位词

题目&#xff1a; 题解&#xff1a; func isAnagram(s, t string) bool {if len(s) ! len(t) {return false}cnt : map[rune]int{}for _, ch : range s {cnt[ch]}for _, ch : range t {cnt[ch]--if cnt[ch] < 0 {return false}}return true }

Temporal-Kit 及 Ebsynth-流程

https://www.youtube.com/watch?vBL77HVIviJM 预处理 Ebsynth-流程

全国区块链职业技能大赛第八套区块链产品需求分析与方案设计

任务1-1:区块链产品需求分析与方案设计 医疗健康平台中涉及到医院、医生、患者等参与方,他们需要在区块链医疗健康平台中完成账户注册、身份上链、挂号就诊、查询病例等多种业务活动。通过对业务活动的功能分析,可以更好的服务系统的开发流程。基于医疗健康平台系统架构,以…

PyTorch实战:深度解析Tensor归一化技巧与应用

PyTorch Tensor 归一化&#xff1a;理解、应用及实现 在机器学习和深度学习中&#xff0c;数据预处理是一个关键的步骤。其中&#xff0c;对于某些情况下&#xff0c;特别是生产的环境&#xff0c;数据归一化是一项必不可少的任务。 在 PyTorch 中&#xff0c;对于 Tensor 的…

【SpringBoot配置文件application.yaml】笔记

详细内容见官方文档Common Application Properties 使用application.yaml进行简单配置 第一步&#xff1a;创建WebDemo第二步&#xff1a;创建application.yaml配置文件注意&#xff1a; 第三步&#xff1a;验证自己创建的yaml文件是否生效测试&#xff1a;思考&#xff1a;如…

算法刷题笔记 八数码(C++实现)

文章目录 题目描述基本思路实现代码 题目描述 在一个33的网格中&#xff0c;1∼8这8个数字和一个x恰好不重不漏地分布在这33的网格中。例如&#xff1a; 1 2 3 x 4 6 7 5 8 在游戏过程中&#xff0c;可以把x与其上、下、左、右四个方向之一的数字交换&#xff08;如果存在&…