新闻详情

新闻详情

首页 / 资讯中心 / 详情

3种语言身份证号校验完整示例:别在正则上卡半天

发布时间:2026/11/1 11:16:06来源:尧图网络
3种语言身份证号校验完整示例:别在正则上卡半天
3种语言身份证号校验完整示例:别在正则上卡半天 配置环境就卡半天,改个校验逻辑还要查半天文档?别闹了。 做后端或者前端,身份证号校验是绕不开的坎。很多人上来就写正则,结果发现 GB 11643-1999 标准里的校验位算法、出生日期合法性、地区码有效性,光靠一个正则根本搞不定。今天直接把 Python、JavaScript、Java 三套主流语言的 完整示例 拍在桌上,代码可直接复制运行,原理讲透,坑提前踩好。 1. 三种方案定位:谁适合谁 先说结论,别选错工具。 Python 适合快速原型、数据清洗、爬虫脚本。它的 re 模块和字符串切片足够处理绝大多数校验场景,开发效率最高。缺点?生产环境性能一般,不适合高并发网关。 JavaScript 是前端标配。用户填完表单,身份证号校验必须在浏览器端第一时间拦截,不然请求打过去被后端拒了,体验极差。JS 方案要兼顾兼容性和体积,不能引入重型库。 Java 是后端服务主力。Spring Boot 里做参数校验,或者微服务网关统一拦截,Java 方案要线程安全、可集成 Bean Validation。性能要求高时,缓存校验结果能省不少 CPU。 三者的核心差异,看这张表:维度 Python JavaScript Java执行环境 服务端脚本、数据管道 浏览器、Node.js JVM、微服务、网关校验位计算 原生整型,无溢出风险 需用 BigInt 或拆位计算 原生 long,需注意 18 位末位是 X日期校验 datetime 模块直观 Date 对象有坑,推荐手动比对 LocalDate 线程安全,推荐地区码校验 需自行维护映射表 前端可预置精简表 可集成数据库或 Redis 缓存正则支持 re 模块强大 引擎差异大,建议手动实现 Pattern 编译复用,性能好典型场景 数据清洗、ETL、快速验证 表单前置校验、小程序 服务端权威校验、API 网关2. 核心原理:别只背正则 很多人以为 身份证号校验 就是套个正则,错。真正的校验分三层: 第一层:格式校验。18 位,前 17 位数字,末位数字或 X。地区码 6 位,出生日期 8 位,顺序码 3 位,校验码 1 位。 第二层:逻辑校验。出生日期必须是真实存在的日期,不能是 2025 年 13 月 40 号。顺序码第 17 位是性别,奇数男,偶数女。 第三层:校验位校验。这是最容易被忽略的。前 17 位数字分别乘以权重因子 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,求和后对 11 取模,余数对应校验码映射表:1,0,X,9,8,7,6,5,4,3,2。 根据 GB 11643-1999《公民身份号码》 国家标准,以及 公安部开发者文档 中关于人口信息校验的技术规范,这三层缺一不可。只查格式,假号一抓一大把;加上校验位,错误率能降 90% 以上。 3. 代码写法对比:三套完整示例 Python 版本:简洁直接 import re from datetime import datetimedef validate_id_card(id_card: str) - bool:# 1. 格式校验:18位,前17数字,末位数字或Xif not re.match(r'^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$', id_card):return False# 2. 日期校验birth_str = id_card[6:14]try:datetime.strptime(birth_str, %Y%m%d)except ValueError:return False# 3. 校验位校验weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]check_map = '10X98765432'total = sum(int(id_card[i]) * weights[i] for i in range(17))expected = check_map[total % 11]return id_card[-1].upper() == expected逐行讲解:正则里 ^ 和 $ 锁定首尾,防止前后混入空格。 (18|19|20)\d{2} 限制年份范围,避免 1700 年或 2100 年。 (0[1-9]|1[0-2]) 月份 1-12,(0[1-9]|[12]\d|3[01]) 日期 1-31,再配合 datetime.strptime 二次确认,杜绝 02 月 30 日。 校验位计算用列表推导式,一行搞定,Python 的优势就在这里。JavaScript 版本:前端友好 function validateIdCard(idCard) {if (!/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/.test(idCard)) {return false;}const birthStr = idCard.substring(6, 14);const year = parseInt(birthStr.substring(0, 4));const month = parseInt(birthStr.substring(4, 6));const day = parseInt(birthStr.substring(6, 8));// 手动日期校验,避免 Date 对象时区坑if (month 1 || month 12 || day 1 || day 31) return false;const daysInMonth = new Date(year, month, 0).getDate();if (day daysInMonth) return false;const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];const checkMap = '10X98765432';let sum = 0;for (let i = 0; i 17; i++) {sum += parseInt(idCard[i]) * weights[i];}return idCard[17].toUpperCase() === checkMap[sum % 11]; }避坑点:别用 new Date(birthStr)。不同浏览器对 YYYYMMDD 解析不一致,有的直接返回 Invalid Date。手动拆年月日,用 new Date(year, month, 0).getDate() 获取当月天数,最稳。 parseInt 前确保是数字,否则 NaN 会污染求和。 前端校验只是前置拦截,绝不能替代后端校验。用户能改 DOM,能抓包,能直接调 API。Java 版本:后端权威 import java.time.LocalDate; import java.util.regex.Pattern;public class IdCardValidator {private static final Pattern ID_PATTERN = Pattern.compile(^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$);private static final int[] WEIGHTS = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};private static final String CHECK_MAP = 10X98765432;public static boolean validate(String idCard) {if (idCard == null || !ID_PATTERN.matcher(idCard).matches()) {return false;}String birthStr = idCard.substring(6, 14);int year = Integer.parseInt(birthStr.substring(0, 4));int month = Integer.parseInt(birthStr.substring(4, 6));int day = Integer.parseInt(birthStr.substring(6, 8));try {LocalDate.of(year, month, day);} catch (Exception e) {return false;}int sum = 0;for (int i = 0; i 17; i++) {sum += (idCard.charAt(i) - '0') * WEIGHTS[i];}return String.valueOf(idCard.charAt(17)).equalsIgnoreCase(String.valueOf(CHECK_MAP.charAt(sum % 11)));} }性能优化:Pattern 是线程安全的,static final 编译一次,多次复用,避免每次 matcher 重新编译。 LocalDate.of 比 SimpleDateFormat 线程安全且快,Java 8+ 项目首选。 高并发场景下,可对 idCard - boolean 结果加一层 Caffeine 或 Redis 缓存,重复查询直接命中。4. 适用场景与选型建议 前端表单:选 JavaScript。用户体验第一,输入失焦即校验,红色提示框比请求失败强一百倍。代码控制在 50 行内,不要引入 lodash 或 dayjs 这种重型依赖,就为校验一个 ID。 数据清洗与 ETL:选 Python。几百万条历史数据,要过滤掉假号、错号,Python 的 pandas 配合上面的校验函数,apply 一下,半小时跑完。Java 写这个纯属脱裤子放屁。 后端 API 与微服务网关:选 Java。Spring Boot 里集成 Bean Validation,自定义 @ValidIdCard 注解,所有入口统一拦截。Java 的 Pattern 编译复用,QPS 上万也不虚。如果校验逻辑复杂,比如要关联地区码、性别、年龄限制,Java 的面向对象优势就出来了,可以扩展成 IdCardInfo 对象,包含解析后的出生日期、性别、地区。 Node.js 后端:用 JavaScript 版本,但要注意 BigInt。如果未来要处理 18 位以上扩展编码,或者做批量求和,Number 精度可能不够,提前用 BigInt 封装。 避坑清单:末位 X 的大小写:用户可能输入小写 x,必须 toUpperCase 或 equalsIgnoreCase 处理。 出生日期跨世纪:1999 年、2000 年、2100 年,正则里 (18|19|20) 要覆盖。 地区码 0 开头:正则首位 [1-9] 已经排除,但内部 6 位地区码允许 0,别写死成 \d{5}。 不要信任前端:前端校验只是 UX,后端必须再校验一遍。安全是后端的事,体验是前端的事,别混。 日志脱敏:打印日志时,身份证号中间 8 位必须打码,110101********1234,否则违反《个人信息保护法》,出事就是大事。5. 进阶:地区码与性能优化 校验位只是基础,真正复杂的业务要查地区码。6 位地区码前 2 位是省,中间 2 位是市,最后 2 位是区县。可以维护一个精简的映射表,比如: {110000: 北京市,310000: 上海市,440000: 广东省 }前端预置 Top 100 地区,覆盖 95% 用户;后端查数据库或 Redis,全量地区码。如果业务需要精确到区县,建议用 GeoHash 或行政区划编码库,别自己硬编码。 性能上,身份证号校验 的 CPU 开销主要在正则匹配和字符串操作。高并发下,可以用 Bloom Filter 预过滤明显错误的格式,再走完整校验。或者,把校验结果缓存 24 小时,同一个 ID 短期内重复请求,直接返回缓存。 还有,别用正则校验日期。正则能匹配 20231345,但 datetime 或 LocalDate 知道 13 月不存在。正则负责格式,原生日期类负责逻辑,各司其职。 结语 身份证号校验 不是背正则,是理解 GB 11643-1999 标准里的校验位算法,是分清前端拦截和后端权威的边界,是知道 Python 适合跑数据、Java 适合扛并发、JavaScript 适合保体验。 代码都给你了,完整示例 可以直接拷走用。配置环境还卡?大概率是依赖版本问题,Python 查 requirements.txt,Java 查 pom.xml,JS 查 package.json,别把校验逻辑的锅甩给环境。 还有什么不懂的?评论区留言挨个回。是正则匹配不上?是校验位算错?还是前端跨域问题?直接说,看到就答。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/1 1:42:41

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/1 2:34:07

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/1 2:01:57

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/1 3:13:10

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/1 2:11:52

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/1 3:23:38

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉