Python实现统一社会信用代码合法性校验

Python实现统一社会信用代码合法性校验

1 统一代码的构成

1.1 结构

​ 统一代码由十八位的阿拉伯数字或大写英文字母(不使用I、O、Z、S、V)组成,包括第1位登记管理部门代码、第2位机构类别代码、第3位第8位登记管理机关行政区划码、第9位第17位主体标识码(组织机构代码)、第18位校验码五个部分。

1.2 代码及说明

1.2.1 第1位:登记管理部门代码

​ 登记管理部门代码使用阿拉伯数字或大写英文字母表示,登记管理部门代码标识如下:

djglbmdm={'1':'机构编制','2':'外交','3':'司法行政','4':'文化','5':'民政','6':'旅游','7':'宗教','8':'工会','9':'工商','A':'中央军委改革和编制办公室','N':'农业','Y':'其他'}

1.2.2 第2位:机构类别代码

​ 机构类别代码使用阿拉伯数字或大写英文字母表示,机构类别代码如下:

# 不同登记管理部门下相同机构类别代码代表的机构类别不同
jglbdm={'1':{'1':'机关','2':'事业单位','3':'编办直接管理机构编制的群众团体','9':'其他'},
        '2':{'1':'外国常驻新闻机构','9':'其他'},
        '3':{'1':'律师执业机构','2':'公证处','3':'基层法律服务所','4':'司法鉴定机构','5':'仲裁委员会','9':'其他'},
       '4':{'1':'外国在华文化中心','9':'其他'},
       '5':{'1':'社会团体','2':'民办非企业单位','3':'基金会','9':'其他'},
       '6':{'1':'外国旅游部门常驻代表机构','2':'港澳台地区旅游部门常驻内地(大陆)代表机构','9':'其他'},
       '7':{'1':'宗教活动场所','2':'宗教院校','9':'其他'},
       '8':{'1':'基层工会','9':'其他'},
       '9':{'1':'企业','2':'个体工商户','3':'农民专业合作社'},
       'A':{'1':'军队事业单位','9':'其他'},
       'N':{'1':'组级集体经济组织','2':'村级集体经济组织','3':'乡镇级集体经济组织','9':'其他'},
       'Y':{'1':''}}

1.2.3 第3位~第8位:登记管理机关行政区划码

​ 登记管理机关行政区划码使用阿拉伯数字表示。按照GB/T 2260编码。

1.2.4 第9位~第17位:主体标识码(组织机构代码)

​ 主体标识码使用阿拉伯数字或大写英文字母表示。按照GB 11714编码。

1.2.5 第18位:校验码

​ 校验码使用阿拉伯数字或大写英文字母表示。校验码计算方法参照GB/T 17710。
​ 校验码按式如下公式计算:
C 18 = 31 − M O D ( ∑ i = 1 17 C i × W i , 31 ) C_{18}=31-MOD(\sum_{i=1}^{17}C_{i}\times W_{i},31) C18=31MOD(i=117Ci×Wi,31)
​ 式中:
​ MOD(n,m) ——整数求余函数,例如:函数MOD(31,31)的值为0;

​ i ——代码字符 从左到右的位置序号;

​ Ci ——第i位置上的代码字符的值,字符对应的值如下:

dmci={'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}

​ C18 ——校验码;

​ Wi ——第i位上的加权因子,Wi= MOD(3(i-1) ,31) ,加权因子如下:

# i 位置列表
i=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
# wi 位置对应的加权因子
wi=[1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28]

​ 当MOD函数值为1(即C18 = 30)时,校验码应用符号Y表示;当MOD函数值为0(即C18 = 31)时,校验码用0表示。

1.2.6 校验码计算方法实例

​ 某统一代码前17位为91350100M000100Y4,其第18位校验码可按下列步骤与方法计算。
​ 第一步:列出代码前17位字符位置序号i相对应的各个位置上的字符值Ci

# M:21,Y:30
ci=[9,1,3,5,0,1,0,0,21,0,0,0,1,0,0,30,4]

​ 第二步:列出与字符位置序号i相对应的加权因子值Wi

# wi 位置对应的加权因子
wi=[1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28]

​ 第三步:计算与字符位置序号i相对应的乘积Ci × Wi

# ci[j]*wi[j]
ciwi=[]
for j in range(0,17):
    ciwi.append(ci[j]*wi[j])

​ 第四步:计算级数之和。
∑ i = 1 17 C i × W i = 1640 \sum_{i=1}^{17}C_{i}\times W_{i} =1640 i=117Ci×Wi=1640
​ 第五步:计算整数求余函数MOD。

​ 级数之和1640模31余28,即MOD(1640,31)值为28。

​ 第六步:求出校验码字符值。

​ C18=31-28=3

​ 第七步:查出校验码字符。

​ 校验码字符值18对应的字符为3,该统一代码为91350100M000100Y43

以上参考:中华人民共和国国家标准 GB 32100-2015《法人和其他组织统一社会信用代码编码规则》

2 Python代码实现


def check_social(code):
    #统一代码由十八位的阿拉伯数字或大写英文字母(不使用I、O、Z、S、V)组成
    valid_char='0123456789ABCDEFGHJKLMNPQRTUWXY'
    invlid_char='IOZSV'
    modulus=31
    if code is None or code.isspace():
        return False
    #位数校验 18 位
    if len(code)!=18:
        return False
    codeu = code.upper()
    #含有不使用大写英文字母
    for i in invlid_char:
        if i in codeu:
            return False
    #不在有效字符范围内
    for i in code:
        if not(i in valid_char):
            return False
    #前两位登记管理部门代码和机构类别代码
    d_o_code=['11','12','13','19','21','29','31','32','33','34','35','39',
              '41','49','51','52','53','59','61','62','69','71','72','79',
              '81','89','91','92','93','A1','A9','N1','N2','N3','N9','Y1']
    if not(code[0:2] in d_o_code):
        return False
    #3-8位登记管理机关行政区划码先不检测了
    #9-17位主体标识码(组织机构代码)先不拿出来校验了
    #第18位校验码,这部分是关键
    #第i位置对应的加权因子
    wi=[1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28]
    #第i位置上的字符对应值
    corres_value={'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}
    #前17位字符位置序号i相对应的各个位置上的字符值
    ci=[]
    for v in code[0:17]:
        j=corres_value.get(v)
        ci.append(j)
    #计算与字符位置序号i相对应的乘积
    ciwi=[]
    for i in range(len(ci)):
        ciwi.append(ci[i]*wi[i])
    #计算级数之和
    ciwi_sum=sum(ciwi)
    #级数之和求余,求出校验码字符值
    c18 = modulus-ciwi_sum % modulus
    #查出校验码字符
    if c18 == modulus:
        c18=0
    check_code=None
    for k,v in corres_value.items():
        if v == c18:
            check_code=k
            break
    if check_code==code[17]:
        return True
    else:
        return False
    

3 未检测部分

3.1 管理部门行政区划代码

​ 全国行政区划代码比较多,在本文实现代码中就没有做校验。

3.2 组织机构代码

​ 组织机构代码也有待定的规则,本文实现代码中没有做校验,有兴趣的可做补充!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值