跳到主要内容
实用工具2026-10-27Begin6 分钟阅读

统一社会信用代码校验位怎么算:GB 32100 结构、字符集与加权算法详解

做供应商主数据、开票信息核对、或者清洗一批从工商系统导出的 Excel——你一定撞过这串 18 位的「数字字母混合码」。它不是随机串,也不是十六进制,校验位更不是身份证那套模 11。本文把统一社会信用代码(USCC)的结构、字符集和校验算法一次讲透,所有结论都可以在 统一社会信用代码校验工具 里当场验证——它在浏览器本地跑同样的算法,代码不出设备。

为什么表单校验总写错

三个特性让「想当然」的校验逻辑翻车:

  1. 不是所有字母都合法。I、O、S、V、Z 五个字母永远不会出现。一个宽松的 [A-Z0-9]{18} 正则会放过永远不可能存在的码,脏数据静默入库。
  2. 校验位是模 31,不是模 10 或模 11。身份证(GB 11643)用 ISO 7064 MOD 11-2,很多库把身份证校验逻辑套到信用代码上——直接误杀合法码。
  3. O 不存在,但 U、W、Y 存在。OCR 或人工「自动纠错」把 0 改成 O 是数据清洗的头号污染源;反过来「把所有元音都删掉」的清洗规则又会误伤合法的 U/W/Y。

18 位结构逐段拆解

位置长度字段说明
11登记管理部门1 机构编制(机关事业单位)、5 民政(社会组织)、9 市场监管(企业)、Y/N 其他
21机构类别含义随部门变化;9(工商/市监)下:1 企业、2 个体工商户、3 农民专业合作社、9 其他
3–86登记管理机关行政区划码形如 110000(北京)、440300(深圳)——是登记机关属地线索,不是邮政编码
9–179主体标识码原组织机构代码并入而来,事实上的唯一序号
181校验码由前 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/ZOCR 或人工「纠错」(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 至少见过一例。