资讯动态

ValidX 统一社会信用代码验证详解:18位代码的构成规则

发布时间:2026/10/14 10:24:09 来源:尧图企业网站定制
统一社会信用代码验证详解18位代码的构成规则 目录引言一、从多头编码到一照一码18 位代码的由来二、18 位代码的解剖五段式结构三、字符集31 个字符与排除名单四、校验码算法加权求和与 mod 31五、双层校验第 17 位与第 18 位六、ValidX UnifiedSocialCreditCode 规则解剖七、实战企业开户与供应商准入八、边界与坑总结项目地址引言统一社会信用代码Unified Social Credit CodeUSCC是中国境内法人和其他组织的身份证号。企业开户、开票、供应商准入、招投标、年报公示处处都要填它。一个 18 位字符串看着像纯数字但里面有字母、有校验位、甚至有嵌套的另一个校验码——比身份证号复杂得多。先给结论校验统一社会信用代码也分两层层次回答的问题手段算法层位数、字符集、校验码对不对本文主角18 位结构 mod 31 校验登记层这个组织真实存在吗状态正常吗国家企业信用信息公示系统、信用中国查询格式校验只是入场券。本文聚焦算法层18 位代码由哪几段构成、为什么字符集只有 31 个、校验码怎么算、ValidX 的UnifiedSocialCreditCode实现了什么以及没实现什么。一、从多头编码到一照一码18 位代码的由来在 2015 年之前一个企业要面对好几套身份编码旧编码发证/管理部门位数现状组织机构代码质检现代码中心9 位被统一代码吸收工商营业执照注册号工商15 位被统一代码吸收税务登记证号税务15~20 位被统一代码吸收统计登记证号统计—被统一代码吸收社会保险登记证号人社—被统一代码吸收多头编码导致同一个组织在不同系统里身份不一致数据对接时全靠一张脆弱的手工映射表。2015 年起国家推行**“一照一码”**由登记部门核发加载统一社会信用代码的营业执照代码由全国组织机构统一社会信用代码数据服务中心代码中心按统一规则生成——一份代码取代上面全部编码各登记管理部门据此共享信息。时间线分步实施、逐步扩围2015-10-01起新设企业、农民专业合作社率先领取三证合一后的新执照工商 质监 税务三证合一2016-10-01起扩为五证合一再并入统计、社保机关、事业单位、社会团体等各类主体分批纳入存量企业于2017 年底前完成换照。编码规则本身由GB 32100-2015《法人和其他组织统一社会信用代码编码规则》规定。本文讨论的所有能过/不能过判定都以这套规则为准。二、18 位代码的解剖五段式结构18 位 1 位登记管理部门代码 1 位机构类别代码 6 位行政区划码 9 位主体标识码 1 位校验码段位次长度含义登记管理部门代码第 1 位1哪个部门登记机构编制/民政/市场监管…机构类别代码第 2 位1在该部门下的机构类别企业/个体户/合作社…登记管理机关行政区划码第 3~8 位6登记机关所在地GB/T 2260 县级以上区划码主体标识码组织机构代码第 9~17 位9主体唯一标识前 8 位本体 第 17 位自身校验位校验码第 18 位1对前 17 位整体计算的校验字符用官方示例91350100M000100Y43ValidX README 同款示例逐位解剖位次123456789101112131415161718字符91350100M000100Y43归属管理部门机构类别行政区划 350100福州组织机构代码本体 M000100Y旧校验新校验第 1、2 位是组合语义——同一位数字在不同部门下含义不同必须连起来读。常见前缀速查前缀登记管理部门机构类别91市场监管原工商企业92市场监管原工商个体工商户93市场监管原工商农民专业合作社11机构编制机关12机构编制事业单位51民政社会团体52民政民办非企业单位社会服务机构53民政基金会第 1 位取值约在 1~9 之间机构编制、外交、司法行政、文化、民政、市场监管、工会等各占其位0 不分配给任何管理部门第 2 位的具体含义要回到第 1 位所在部门去查——完整对照表见 GB 32100-2015 附录。三、字符集31 个字符与排除名单统一社会信用代码用阿拉伯数字和英文字母表示但字母并非 A~Z 全量可用——排除了I、O、S、V、Z五个排除字符排除理由防混淆I与数字 1 混淆O与数字 0 混淆Z与数字 2 混淆S与数字 5 混淆V与 U/Y 手写易混所以合法字符集共31 个0~910 个 排除后剩余的 21 个大写字母0 1 2 3 4 5 6 7 8 9 A B C D E F G H J K L M N P Q R T U W X Y这个排除名单直接决定了验证器的第一步任何出现 I/O/S/V/Z 的代码立即非法——哪怕它 18 位、哪怕校验位碰巧也对。这在人工抄写、OCR 识别场景下能挡住大量因笔误产生的脏数据。字符的数值映射也以这 31 字符的位置为准0~9取值 0~9字母从 A10 起按序顺延跳过排除字母字母AHJMNPRTY值101718212223252630注意 J18 紧接 H17因为中间的 I 被排除同理 P23 接 N22跳过 O。四、校验码算法加权求和与 mod 31第 18 位校验码不是随机字符而是由前 17 位算出来的。算法GB 32100-2015C18 CHARSET[(31 − (Σ(Ci × Wi)) mod 31) mod 31]其中Ci 第 i 位字符的取值见上节映射表Wi 第 i 位的加权因子Σ对前 17 位i 1…17求和最后把余数映射回 31 字符集31 − r得到字符下标若结果为 31 则取 0。加权因子表17 个由3^(i-1) mod 31生成——3 是 31 的原根权重序列无重复位次: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 权重: 1 3 9 27 19 26 16 17 20 29 25 13 8 24 10 30 28以91350100M000100Y43为例完整手算一遍位次字符值权重乘积累计1991992113312333927394552713517450019017461126262007001602008001702009M21204206201000290620110025062012001306201311886281400240628150010062816Y303090015281744281121640总和Σ 16401640 mod 31 28校验字符下标 31 − 28 3查字符集第 4 个字符3——恰好等于第 18 位。校验通过。与身份证号做对比能加深理解身份证校验码是mod 11权重 7/9/10/5/8/4/2/1 等校验值 10 记 X统一社会信用代码是mod 31、权重是 3 的幂。别拿身份证那套11 减余数、余 10 记 X的习惯去套它。五、双层校验第 17 位与第 18 位很多文章只说第 18 位是校验码容易让人以为校验只有一层。实际上这个 18 位代码里嵌套着两套校验第 17 位是第 9~16 位组织机构代码本体 8 位的校验位按GB 11714规则计算权重 3/7/9/10/5/8/4/2、mod 11校验值 10 记为 X第 18 位是对第 1~17 位整体按 GB 32100-2015mod 31计算的校验位。还是91350100M000100Y43本体M000100Y的第 17 位应为4——M(21)×3 0×7 0×9 0×10 1×5 0×8 0×4 Y(30)×2 63 5 60 128 128 mod 11 7 → 11 − 7 4 ✓ 第17位确实是 4设计逻辑存量主体的 9 位主体标识码直接沿用原组织机构代码含其自身校验位保证与历史代码库无缝衔接第 18 位再叠加一层整体校验任何一位写错都能被拦下。注意两层校验的算法、字符集、模数都不同。多数验证库包括 ValidX只实现最外层的 mod 31 校验——见下一节的没做什么。六、ValidX UnifiedSocialCreditCode 规则解剖ValidX 的UnifiedSocialCreditCode对应UnifiedSocialCreditCodeValidator源码做了三件事// UnifiedSocialCreditCodeValidator.java节选逻辑等价// 1) 31 字符集排除 I O S V ZCHECK_CODES0123456789ABCDEFGHJKLMNPQRTUWXY;// 2) 加权因子3^(i-1) mod 31WEIGHT{1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28};// 3) isValid空值放行 → 长度 ! 18 拒绝 → 字符不在字符集拒绝 → 校验码比对实测判定矩阵与源码逐一核对输入UnifiedSocialCreditCode说明91350100M000100Y43✅README/标准示例91 企业·福州91310115011524493K✅91 企业·上海浦东演示码123101153982597915✅12 事业单位演示码51310000341672110B✅51 社会团体演示码91350100M000100Y44❌末位篡改校验码不匹配91350100M000100Y4❌17 位少 1 位91350100M000100Y43X❌19 位多 1 位91350100I000100Y43/O/S/V/Z❌出现排除字符91350100m000100y43❌含小写字母91.50100M000100Y43❌含非法符号演示码由作者按同一算法构造校验位合法、形态真实非真实主体真实验证请用登记信息查询平台。使用方式与其它注解一致publicclassEnterpriseDTO{NotBlankUnifiedSocialCreditCode// 社会信用代码格式不正确privateStringcreditCode;NotBlankChineseNameprivateStringlegalPerson;}默认消息键{io.github.vipxieliang.validx.annotation.unified.social.credit.code}中文为社会信用代码格式不正确支持message覆盖与groups。链式 API 对应isUnifiedSocialCreditCode(...)ValidXvValidX.init();if(v.isUnifiedSocialCreditCode(code).failed()){// 格式不过关错误已记入 errors}ValidX “做了什么” 与 “没做什么”校验项ValidX说明18 位长度✅字符集排除 I/O/S/V/Z✅覆盖全 18 位第 18 位 mod 31 整体校验码✅核心算法第 1/2 位取值与组合91/92/93…❌只按 31 字符集放行99、0x组合不拦第 3~8 位必须是数字行政区划❌字母也能过只要整体校验码对第 17 位内层 GB 11714 校验❌只做外层 mod 31行政区划真实性310115 是不是浦东❌需要登记库没做什么不是偷懒而是分层设计——算法层用一串常数就能挡掉 99% 的手误语义层需要登记库数据属于业务侧责任见第八节。七、实战企业开户与供应商准入场景一企业开户表单注解模式publicclassOpenAccountDTO{NotBlankUnifiedSocialCreditCodeprivateStringcreditCode;// 营业执照上的统一社会信用代码NotBlankChineseNameprivateStringcompanyName;NotBlankChineseIdCardprivateStringlegalPersonIdCard;}场景二供应商批量入库链式 APIValidXvValidX.init();for(SupplierRowrow:rows){Stringcoderow.getCreditCode().trim().toUpperCase();// 清洗去首尾空白 大写if(v.isUnifiedSocialCreditCode(code).failed()){badRows.add(code - v.getErrors());// 只做算法层校验continue;}// 算法层通过后再调用登记库 API 核验主体真实存在if(!registerCenter.exists(code)){badRows.add(code - 登记库查无此主体);}}场景三写进 Spring ValidationPostMapping(/enterprise)publicResultcreate(ValidRequestBodyEnterpriseDTOdto){// 进入这里时 NotBlank/UnifiedSocialCreditCode 已全部通过returnenterpriseService.create(dto);}八、边界与坑1. 空值放行必填交给NotBlankUnifiedSocialCreditCode对null/空串返回合法——是否必填和格式是否对照例拆开声明NotBlank// 管必填UnifiedSocialCreditCode// 管格式privateStringcreditCode;2. 校验码通过 ≠ 主体存在语义缺口要心里有数下面三个码能通过 ValidX校验位按规则重算后合法但在现实中不可能存在演示码语义问题04JURQ283FQEFLCR6Y第 1 位 00 不分配给任何管理部门997JH4BXKFLJ2K0XT199 组合无对应登记部门/类别91AAAAAAYUYU122BT4第 3~8 位行政区划应是 6 位数字真实的准入流程必须在算法层之上叠加登记信息核验国家企业信用信息公示系统、信用中国的查询接口。一句话UnifiedSocialCreditCode挡住长得不像的拦不住编得圆的。3. 只认大写收数前统一清洗字符集只有大写字母。用户从 PDF、营业执照 OCR 出来可能带小写、空格、首尾空白入库前统一trim().toUpperCase()再去校验字符串中间不允许出现空格/连字符带格式粘贴会直接判错这符合标准——官方代码不设分隔符。4. 第 17 位是代码里的代码外层校验过了不代表内层组织机构代码校验位GB 11714 mod 11一定成立。ValidX 只做外层。若你的系统要对存量组织机构代码库做精确比对、或想更早拦截伪造内层伪造难度更高可自研叠加取第 9~16 位用 3/7/9/10/5/8/4/2 权重做一次 mod 11 校验比对第 17 位。5. 别用纯数字 18 位的假设很多校验器新手会写^\d{18}$——但合法代码里字母可以出现在第 9 位之后示例里的 M、Y。正则只该约束字符集和长度不能假设全数字。6. 换照过渡期老数据里可能有旧码2017 年底前存量的旧注册号/组织机构代码在部分历史系统里仍会出现。做数据对接时旧码需要映射到新码或单独标识别当脏数据直接拒绝——先判断字段体系再决定校验规则。7. 校验码算法别拿身份证的 mod 11 硬套身份证校验是 mod 11 权重 {7,9,10,5,8,4,2,1,…}、校验值 10 记为 X统一社会信用代码是mod 31 3 的幂权重 31 字符集。两套体系从字符集到模数完全不同写死任何一套去验另一套都会全盘报错。总结观点结论18 位怎么来的2015 年起一照一码取代组织机构代码/注册号/税务登记号等多套编码代码结构管理部门(1) 机构类别(1) 行政区划(6) 主体标识码(9) 校验码(1)字符集0~9 A~Y排除 I/O/S/V/Z共 31 字符只认大写校验算法权重 3^(i-1) mod 31Σ(Ci×Wi) mod 3131 − 余数映射回字符集双层校验第 17 位内层 GB 11714 mod 11组织代码校验第 18 位外层 GB 32100 mod 31ValidX 边界算法层三项全覆盖第 1/2 位组合、行政区划数字性、内层校验、登记真实性均不校验别踩的坑mod 11 硬套、纯数字正则、小写不收、格式码带空格/连字符直接判错统一社会信用代码验证的正确姿势算法层交给UnifiedSocialCreditCode长度 31 字符集 mod 31 校验码格式过了再走登记信息核验确认主体真实存在——一层挡手误一层挡伪造各司其职。项目地址GitHubhttps://github.com/vipxieliang/ValidXGiteehttps://gitee.com/vipxieliang/ValidXMaven Centralhttps://central.sonatype.com/artifact/io.github.vipxieliang/validx

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑