Python实现统一社会信用代码校验(GB32100-2015)

统一社会信用代码国标校验

  统一社会信用代码的校验最准确的方式,就是通过调用正式的接口或者对接统一社会信用代码数据库。前者,我们需要支付一定的费用。后者,实施难度较大。在资源有限的情况下,我们可以参照GB- 32100-2015实现代码,对统一社会信用代码合法性作出判断。

统一社会信用代码国标校验规则

  简单来说,国标的校验规则就是取统一社会信用代码的前17位(自左至右),每一位的字符/数字都有其对应的值,公式(1)最终求出的值经过转化后与统一社会信用代码的第十八位进行比对,一致则代表统一社会信用代码合法,不一致则代表统一社会信用代码不合法。
C 18 = 31 − M O D ( ∑ i = 1 17 × W i , 31 ) \begin{aligned}C_{18}=31-MOD(\sum_{i=1}^{17}\times W_{i},31)\end{aligned} C18=31MOD(i=117×Wi,31)
其中, C i C_{i} Ci标识字符/数字对应的值, M O D ( m , n ) MOD(m,n) MOD(m,n)标识 m m m n n n后的余数, W i W_i Wi表示每一位字符/数字的加权因子,可由 W i = M O D ( 3 i − 1 , 31 ) W_i=MOD(3^{i-1},31) Wi=MOD(3i1,31)计算得到。需要注意的是,当 31 − M O D ( m , n ) 31-MOD(m,n) 31MOD(m,n)的结果为31时,校验码用0表示

  特别地,摘抄一段国标中统一代码的机构描述“统一社会信用代码由十八位的阿拉伯数字或大写英文字母(不使用I、O、Z、S、V)组成,包括第1位登记管理部门代码、第2位机构类别代码、第3位到第8位登记管理机关行政区划码、第9位到第17位主体标识码(组织机构代码)、第18位校验码五个部分”。由此,我们可以根据代码的对应关系解析出隐藏的信息(详细的代码标识可参照GB- 32100-2015)。

示例说明

  以“11320000MB151840XJ”为例。

  1. 首先,根据代码字符集表获取“11320000MB151840XJ”中每个代码字符对应的代码字符数值。
代 码 字 符 代码字符 11320000MB151840X
字 符 数 值 字符数值 11320000211115184029
表一 代码字符集表
代码字符代码字符数值
00
11
22
33
44
55
66
77
88
99
A10
B11
C12
D13
E14
F15
G16
H17
J18
K19
L20
M21
N22
P23
Q24
R25
T26
U27
W28
X29
Y30
  1. 将对应位置的字符值乘相应的权重并求和。
    s u m = 1 × 1 + 1 × 3 + 3 × 9 + 2 × 27 + 0 × 19 + 0 × 26 + 0 × 16 + 0 × 17 + 21 × 20 + 11 × 29 + 1 × 25 + 5 × 13 + 1 × 8 + 8 × 24 + 4 × 10 + 0 × 30 + 29 × 28 = 1966 sum =1\times1+1\times3+3\times9+2\times27+0\times19+0\times26+0\times16+0\times17+21\times20+11\times29+1\times25+5\times13+1\times8+8\times24+4\times10+0\times30+29\times28=1966 sum=1×1+1×3+3×9+2×27+0×19+0×26+0×16+0×17+21×20+11×29+1×25+5×13+1×8+8×24+4×10+0×30+29×28=1966
表二 各位置权重表
i i i1234567891011121314151617
W i W_i Wi139271926161720292513824103028
  1. 求出校验码 r e s res res并与 C 18 C_{18} C18进行比对。
    r e s = 31 − M O D ( 1966 , 31 ) = 18 res=31-MOD(1966,31)=18 res=31MOD(1966,31)=18
    易得18对应的字符为 J J J,与 C 18 C_{18} C18一致,“11320000MB151840XJ”通过国标校验,这里,通过国标校验仅能代表编码规则是正确的,如果需要进一步确定统一社会信用代码是否真实存在,还需通过其他渠道。

Python代码实现(仅实现GB- 32100-2015中的规则)

def scVerificate(sc):
    # 校验公式(见GB 32100-2015):C_18 = 31-mod(sum(C_i*W_i),31)(i=1,2,...,17),其中C_i为组织机构代码的第i位字符在国标中对应的值,W_i为第i位置的加权因子,C_18为校验码
    # 统一社会信用代码中不使用I,O,Z,S,V
    result = False;
    codeDict = {
                '0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,
                'A':10,'B':11,'C':12, 'D':13, 'E':14, 'F':15, 'G':16, 'H':17, 'J':18, 'K':19, 'L':20, 'M':21, 'N':22, 'P':23, 'Q':24,
                'R':25, 'T':26, 'U':27, 'W':28, 'X':29, 'Y':30};
    
    weights = ['1', '3', '9', '27', '19', '26', '16', '17', '20', '29', '25', '13', '8', '24', '10', '30', '28'];
    sum = 0
    
    for i in range(len(sc) - 1):
        #print(codeDict[sc[i]]);
        sum += codeDict[sc[i]] * int(weights[i]);
    
    mod = 31-sum % 31    

    
    if(mod == codeDict[sc[-1]]) or ((mod == 31) and codeDict[sc[-1]] == 0):
        result = True;
        
    return result;
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值