身份证校验位怎么算:GB 11643 的 MOD 11-2 算法与结尾 X 的由来
做实名表单、清洗一批实名数据、或者排查「为什么用户的身份证号总是校验不过」——你迟早会撞上那几个经典问题:结尾的 X 存不进 int 字段、小写 x 校验不过、有人身份证 15 位。本文把 18 位身份证号的结构、校验位算法和真实数据里的脏法一次讲透,所有结论可以在 身份证校验工具 里当场验证——纯浏览器本地计算,贴任何号码都不出设备。
18 位逐段拆解
| 位置 | 字段 | 说明 |
|---|---|---|
| 1–2 | 省份 | 11 北京、31 上海、44 广东……标准表里还预留了 71 台湾、81 香港、82 澳门 |
| 3–6 | 市/县区划 | 与省份合成 6 位登记区划码 |
| 7–14 | 出生日期 | YYYYMMDD,必须是真实日历日期(2 月 30 日这类在校验位之前就该被拒) |
| 15–17 | 顺序码 | 同区划同生日内的分配序号;第 17 位奇偶即性别位——奇男偶女 |
| 18 | 校验码 | 前 17 位按 ISO 7064 MOD 11-2 计算,值为 10 时写作 X |
两个比校验位更便宜的拒绝动作:出生日期必须真实存在、省份前缀必须真实存在。这两行代码拦下的垃圾数据往往比校验位多——因为它们拦的是语义错误,校验位拦的是转录错误。
校验位算法:加权求和取模
前 17 位各自乘固定位权重求和,模 11 后折返:
权重表 = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
v = (12 - (Σ 数字 × 权重) mod 11) mod 11
校验码 = v 的十进制写法(v=10 时写 X)
这张权重表是 2 的幂模 11、从右往左数:第 17 位乘 2¹、第 16 位乘 2²……周期 10 循环(2¹⁰ ≡ 1 mod 11)。和统一社会信用代码是同一族构造——那边是 3 的幂 mod 31,这边是 2 的幂 mod 11,都用了「素数模 + 原根底数」的加权序列。收益也一样:每个权重都是非零剩余,任何单数字替换必被抓;相邻权重永远不同(比值是 2 或其逆,不可能 ≡ 1 mod 11),任何相邻换位也必被抓。这点强于银行卡的 Luhn 算法——Luhn 会漏掉 0/9 这类特定相邻换位。
手算一遍。取 17 位主体 11010119900815001(北京东城 110101,1990-08-15,顺序码 001):
- 前四位贡献:
1×7 +1×9 +0×10 +1×5 = 21; - 17 位总和:199;
199 mod 11 = 1;12 − 1 = 11 → mod 11 = 0;校验位为0。
完整号码 110101199008150010。把顺序码改成 002——区划生日全同、看起来完全合法——正确的校验位就变了,原来的 0 立即被判 checksum 错误。整条链路(含生日与性别解析)可在校验工具里复现。
结尾 X 的三条处理纪律
校验值算出 10 时没有单个十进制数字可写,标准规定记作 X。实务上三条:
- 入库必须是文本列。大约 1/11 的号码以 X 结尾,int 列物理上存不下它们——静默截断或导入报错的经典事故源。已有系统还在用数字列的,迁移时先补这一课。
- 校验前
toUpperCase()+ NFKC 归一化。小写x是转录噪声,全角X(U+FF38)是 PDF/输入法复制 artifact——都是可修复输入,别用「格式错误」一刀切。 - 永远不要「重算校验位并覆写」。那会制造一个格式合法但查无此人的号码,让污染对所有下游校验隐形。校验不过就转人工。
真实数据里最常见的五种脏法
| 症状 | 常见原因 | 处置 |
|---|---|---|
小写 x / 全角 X | 输入法、PDF、OCR | 转大写 + NFKC 后重校 |
O 混入数字段 | OCR「自动纠错」(O 原是 0) | 仅修复场景映射 O→0,禁止一刀切 |
| 只有 15 位 | 1999 年前的旧版号(无世纪位、没有校验位) | 结构性不同,走升级登记流程,别套 18 位校验 |
| 生日 2 月 30 日 / 未来日期 | 生日位敲错 | 校验位之前就拒,报错要说清是哪个字段 |
| 校验通过但人证不符 | 复制错行 / 手滑填了别人的 | 任何校验位都管不了——见下节边界 |
校验能保证什么、不能保证什么
校验位通过的号码只是格式合法。它不能证明号码真实存在、属于提交者本人、或与姓名匹配——那是公安验证服务的职责,本站工具刻意不做这类查询,也因此整段计算都在浏览器内完成,贴真实号码无泄露风险。给下游系统造测试数据时,用中国格式测试数据生成器:区划形状真实、生日真实、校验位正确,且确定是合成号。
隐私提醒顺带说透:身份证号是最高敏感级 PII,任何在线校验器用之前先开 DevTools Network 面板看一眼——上传式的一票否决。
FAQ
X 结尾和出生日期有关系吗? 没有。X 只是校验值算到 10 的写法,约占全部号码的 1/11,与生日无关。
港台澳居民用这个 18 位格式吗?
不用,三地各有自己的证件格式。标准表预留 71/81/82 只是区划占位,实际号码体系不同。本文只覆盖大陆居民身份证。
为什么有些系统里身份证号占 19 个字符?
要么补了空格要么拼了别的字段。号码就是 18 字符,末位可能是 X。
15 位的老号码还能校验吗? 不能按 18 位规则校验——它没有校验位、出生日期没有世纪位。正确姿势是走升级流程换发,代码里识别出来单独标记即可。
同系列:中国标识符
实现注记
工具源码里是一份权重表 + 一张校验映射表,外加一个值得抄的细节:生日真实性用 UTC 往返检查(new Date(Date.UTC(y, m-1, d)) 必须落回同一天),不用月份天数查找表就能拦住 2 月 30 日。我们在野见过的一类 bug:校验器只做大写转换不做 NFKC,全角数字 1990 触发的报错是莫名其妙的「字符集错误」而不是「可修复的全角输入」。这些行为全部由 round-trip 测试钉死(生成 N 个合法号 → 全部通过 → 逐位篡改 → 断言拒绝)。
相关工具
相关文章
统一社会信用代码校验位怎么算:GB 32100 结构、字符集与加权算法详解
18 位统一社会信用代码(GB 32100-2015)完整拆解:登记部门/机构类别/区划/主体标识各段含义、31 字符集(不含 I O S V Z)、加权模 31 校验算法附手算示例、Excel 与代码实现的数据清洗实战。
色盲怎么看你的配色:六种色觉类型的自检方法与安全色板
红绿色盲用户眼里你的界面什么样?介绍六种色觉障碍类型(红/绿/蓝色盲与色弱、全色盲)、矩阵模拟原理、配色自检清单,以及信息不止靠颜色传达的 WCAG 实践。附在线色盲模拟工具。
Markdown 转 Word 交付指南:样式映射与行内降级
把 Markdown 草稿变成可交付的 .docx:pandoc 命令行与浏览器本地转换两条路线,标题/表格/代码块的 Word 原生样式映射对照,行内格式降级清单,以及「可编辑」为什么比「看起来像」更重要。