统一社会信用代码校验位怎么算:GB 32100 结构、字符集与加权算法详解
做供应商主数据、开票信息核对、或者清洗一批从工商系统导出的 Excel——你一定撞过这串 18 位的「数字字母混合码」。它不是随机串,也不是十六进制,校验位更不是身份证那套模 11。本文把统一社会信用代码(USCC)的结构、字符集和校验算法一次讲透,所有结论都可以在 统一社会信用代码校验工具 里当场验证——它在浏览器本地跑同样的算法,代码不出设备。
为什么表单校验总写错
三个特性让「想当然」的校验逻辑翻车:
- 不是所有字母都合法。
I、O、S、V、Z五个字母永远不会出现。一个宽松的[A-Z0-9]{18}正则会放过永远不可能存在的码,脏数据静默入库。 - 校验位是模 31,不是模 10 或模 11。身份证(GB 11643)用 ISO 7064 MOD 11-2,很多库把身份证校验逻辑套到信用代码上——直接误杀合法码。
O不存在,但U、W、Y存在。OCR 或人工「自动纠错」把0改成O是数据清洗的头号污染源;反过来「把所有元音都删掉」的清洗规则又会误伤合法的U/W/Y。
18 位结构逐段拆解
| 位置 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 1 | 1 | 登记管理部门 | 1 机构编制(机关事业单位)、5 民政(社会组织)、9 市场监管(企业)、Y/N 其他 |
| 2 | 1 | 机构类别 | 含义随部门变化;9(工商/市监)下:1 企业、2 个体工商户、3 农民专业合作社、9 其他 |
| 3–8 | 6 | 登记管理机关行政区划码 | 形如 110000(北京)、440300(深圳)——是登记机关属地线索,不是邮政编码 |
| 9–17 | 9 | 主体标识码 | 原组织机构代码并入而来,事实上的唯一序号 |
| 18 | 1 | 校验码 | 由前 17 位加权计算(算法见下) |
北京注册的企业因此以 91 11000 ... 开头:部门 9、类别 1、区划 110000,再接 9 位主体标识和 1 位校验码。
31 字符集:记住「没有 I O S V Z」
GB 32100-2015 的合法字符就这些:
0123456789ABCDEFGHJKLMNPQRTUWXY
数字 0-9 加上去掉 I/O/S/V/Z 的大写字母,共 31 个。排除这五个字母是为了消灭形近混淆(I/1、O/0、S/5、V/U、Z/2)。两个实务推论:
- 数据里出现小写一定是转录问题——标准只认大写。校验前
toUpperCase()是安全且正确的预处理。 - 表单报错信息写「包含 I/O/S/V/Z」比一句「格式不对」有用得多:它直接告诉操作员错在哪,而不是让对方瞎猜。
校验算法:加权模 31
每个字符按它在字符集里的序号取值(0→0……9→9、A→10、B→11……Y→30),乘以固定位权重求和,再模 31:
权重表 = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
校验位序号 = (31 - (Σ 字符序号 × 权重) mod 31) mod 31
校验码 = 字符集[校验位序号]
一个多数中文资料也不提的细节:这张权重表是 3 的幂模 31(1, 3, 9, 27, 19=81 mod 31, 26=243 mod 31, …)。31 是素数且 3 是它的原根,权重序列遍历全部 30 个非零剩余——这正是它能检出单字符替换和大多数换位错误的原因。校验码本身可以是字符集里任何一个字符,包括 0;拒绝尾位为 0 的校验器是错的。
手算一遍。取 17 位主体 91110000MA01AB9C7:
- 逐字符取序号乘权重求和。前四位:
9×1 +1×3 +1×9 +1×27 = 48;依此算完 17 位,总和为 1761; 1761 mod 31 = 25;31 − 25 = 6;字符集第 6 位是6。
所以完整合法码是 91110000MA01AB9C76。改动主体里任意一个字符——比如 MA01 改成 MAO1(字母 O,本身非法)或 MB01(字符合法但码错了,它正确的校验码应是 8 而非 6)——重算的校验位立即对不上。整条链路(含部门/类别解析)可在 校验工具 里复现。
真实数据里最常见的五种脏法
| 症状 | 常见原因 | 处置 |
|---|---|---|
含 I/O/S/V/Z | OCR 或人工「纠错」(O 原是 0、I 原是 1) | 重校时映射 O→0、I→1,禁止一刀切删除 |
全角字符(9、M) | 从中文输入法字段或 PDF 复制 | NFKC 归一化后再校验 |
| 17 位或 19 位 | 表单截断了末位校验码,或粘连了旁边一列银行账号 | 重数长度,18 位没有商量 |
| 中间夹空格/换行 | Excel 单元格换行、PDF 断行 | 去除空白后重校 |
| 字符集合法但校验不过 | 主体位真实输入错误(校验位正在履行职责) | 不要重算并覆写第 18 位,转人工核对 |
最后一行最关键:「重算校验位并覆写」是数据清洗的经典反模式——它产出一个格式合法但什么单位都不指向的码,污染从此对所有下游校验隐形。
校验能告诉你什么、不能告诉什么
通过字符集与校验位检查的码只是格式合法。它不能证明该码在国家企业信用信息公示系统里真实存在、主体仍在营、或与你表格里相邻的公司名匹配。登记状态要以公示系统查询为准——本站工具 刻意只做格式校验、不做登记库查询,也因此整段计算都在浏览器内完成,贴码无泄露风险。
需要给下游系统造测试数据时,你要的是「校验位正确但确定是合成」的码:中国格式测试数据生成器 生成的正是这种——随机主体 + 正确计算的校验位,偏向真实的 91 企业前缀形态。同类中国标识符的格式规则(车牌、身份证)见 中国车牌格式规则全解。
FAQ
信用代码和组织机构代码是一回事吗? 不是。2015 年三证合一后,原 9 位组织机构代码被吸收为信用代码的第 9–17 位。存量数据里可能把旧 9 位码(自带 ISO 7064 模 11 校验)存在标着新码的字段里——迁移清洗的经典 bug 源。
信用代码第一位可以是数字吗?
可以,1、5、9 是最常见的开头。声称「必须字母开头」的规则是把它和别的编码记混了。
小写的信用代码合法吗? 标准只认大写;小写是转录噪声。先转大写再校验。
校验位能兜住所有错误吗? 单字符替换全兜住、多数换位能兜住(权重序列的构造决定的),但对刻意构造的输入无能为力。要确认主体真实性,查公示系统,别指望校验位。
实现注记
工具源码里就是一份可抄的参考实现:31 字符常量、17 项权重表、一个累加循环。实现时踩过两个坑:一是权重表必须定义在「字符集序号空间」而不是「字符值空间」,这里差一个 off-by-one 会让约 1/31 的非法码漏过——抽查根本发现不了;二是 (31 - (sum % 31)) % 31 外层模不能省:sum % 31 == 0 时必须映射到校验码 0,否则数组越界。对照测试过的几个开源校验器,这两个 bug 至少见过一例。
相关工具
相关文章
色盲怎么看你的配色:六种色觉类型的自检方法与安全色板
红绿色盲用户眼里你的界面什么样?介绍六种色觉障碍类型(红/绿/蓝色盲与色弱、全色盲)、矩阵模拟原理、配色自检清单,以及信息不止靠颜色传达的 WCAG 实践。附在线色盲模拟工具。
Markdown 转 Word 交付指南:样式映射与行内降级
把 Markdown 草稿变成可交付的 .docx:pandoc 命令行与浏览器本地转换两条路线,标题/表格/代码块的 Word 原生样式映射对照,行内格式降级清单,以及「可编辑」为什么比「看起来像」更重要。
Word 转 Markdown 怎么转才干净:两条路线与格式保真对照
docx 转 Markdown 教程:pandoc 命令行与浏览器本地转换两条路线对比,标题/表格/图片/自动编号的保真行为,.doc 旧格式、图片体积、合并单元格等常见坑的解法。