身份证归属地查询:调用前如何先做身份证号格式与校验位合法性自检
# 身份证归属地查询:调用前如何先做身份证号格式与校验位合法性自检
> 接口:身份证归属地查询(apiCode=25,接入点 25-3) · 免费 · POST/GET · JSON · 适用人群:前端/后端工程师 · 阅读时间:约 6 分钟
## TL;DR
- 身份证号是 18 位:6 位地区 + 8 位生日 + 3 位顺序 + 1 位校验位。
- 校验位按 GB 11643(ISO 7064 MOD 11-2)计算,可在调用接口**前**本地判定号码是否"形式上合法"。
- 这是**客户端通用知识**,不是 ShowAPI 的功能;目的是少发无效请求、提前拦掉明显乱填的号。
## Why
把一个长度不对、生日不存在、或校验位算不出来的号码发给接口,既浪费调用,又可能返回无意义结果。在调用接口之前,先用一段极轻量的本地校验把"形式上就不合法"的号码拦掉,是性价比最高的前置优化——尤其适合批量场景(见 [批量核验](https://www.showapi.com/guides/idcard-attribution-batch-25))。
## What
| 项 | 说明 |
|----|------|
| 校验对象 | 18 位身份证号的格式与校验位 |
| 标准依据 | GB 11643《公民身份号码》,校验位算法采用 ISO 7064 MOD 11-2 |
| 归属 | 客户端通用实现,**非 ShowAPI 接口能力** |
## How
### 步骤 1:格式与生日初筛
- 长度必须为 18;前 17 位为数字,末位可为数字或 `X`。
- 第 7–14 位为出生日期 `YYYYMMDD`,应能解析为真实日期。
### 步骤 2:校验位计算(MOD 11-2)
```python
def idcard_valid(id_number: str) -> bool:
if not isinstance(id_number, str) or len(id_number) != 18:
return False
if not id_number[:17].isdigit():
return False
# 出生日期粗校验
try:
from datetime import datetime
datetime.strptime(id_number[6:14], "%Y%m%d")
except ValueError:
return False
weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
check_codes = "10X98765432"
s = sum(int(id_number[i]) * weights[i] for i in range(17))
return check_codes[s % 11] == id_number[17].upper()
# 示例:idcard_valid("522423199105047376") -> True/False 取决于实际号码
```
### 步骤 3:不合法就别发接口
校验不通过 → 直接提示用户"号码格式有误",不再发起接口调用。
## 返回示例
本篇不涉及接口返回;接口返回结构见 [返回字段全解](https://www.showapi.com/guides/idcard-attribution-fields-25)。
## 进阶 / 边界
- **自检 ≠ 真实存在**:本地校验只能确认"号码形式上符合国标",不能确认该身份证在公安系统真实存在。要辨真伪仍需权威渠道。
- **地区码可进一步校验**:前 6 位属于国标行政区划代码,可对照官方代码表做二级校验(本文不内置代码表,避免过期)。
- **与接口配合**:通过自检的号码再调接口,拿回籍贯/生日/性别用于业务比对,见 [实名核验集成](https://www.showapi.com/guides/idcard-attribution-verify-25)。
## FAQ
**Q:这段校验是 ShowAPI 提供的吗?**
不是。它是基于国家标准的客户端通用实现,用于在调用接口前过滤形式上非法的号码,不是接口的返回或能力。
**Q:校验通过了就说明身份证是真的吗?**
不能。校验位合法只代表号码"符合编码规则",不代表该号码在现实中真实存在或被某人持有。
**Q:末位的 X 要怎么处理?**
末位校验码可能是 `X`(代表 10),比较时统一转大写处理即可。
**Q:为什么还要调接口,本地不是已经能算了?**
本地只能算出"号码是否合法 + 它编码上对应的地区/生日/性别",但接口的 `address` 是官方反查的完整籍贯串,且可作为你业务里的"第三方佐证"来源;自检只是省掉明显无效的请求。
**Q:地区码校验需要内置一张表吗?**
可选。前 6 位是行政区划代码,对照官方代码表可做更严校验,但代码表会更新,本文不内置以免过期。
## 相关能力 / 下一步阅读
- [身份证归属地查询:用户注册实名核验的集成设计(前端 + 后端)](https://www.showapi.com/guides/idcard-attribution-verify-25)
- [身份证归属地查询:批量核验(Excel/CSV 导入)的循环调用设计](https://www.showapi.com/guides/idcard-attribution-batch-25)
- [身份证归属地查询背后的 18 位编码规则:为何能反推籍贯/生日/性别](https://www.showapi.com/guides/idcard-attribution-number-std-25)
- **本系列共 12 篇**:查看[身份证归属地查询指南总目录](https://www.showapi.com/guides/idcard-attribution-guides-25)