全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一位数字(或大写拉丁字母)校验码组成。
校验码按照以下公式计算:
C9=11−MOD(∑i=18Ci×Wi,11)
式中:
- MOD——代表求余函数;
- i——代表代码字符从左至右位置序号;
- Ci ——代表第i位上的代码字符的值,代码字符机器处理字符数值见下表:
字符 | 0 | 1 | … | 9 | A | B | … | Y | Z |
---|---|---|---|---|---|---|---|---|---|
数值 | 0 | 1 | … | 9 | 10 | 11 | … | 34 | 35 |
- C9 ——代表校验码;
- Wi ——代表第i位上的加权因子,其数值见下表:
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
Wi | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 |
当C9的值为10时,校验码应用大写的拉丁字母X表示;当C9的值为11时校验码用0表示。
为便于人工识别,应使用一个连字符“-”分隔本体代码与校验码。机读时,连字符省略。表示形式为:xxxxxxxx-X
所以,我们写一个方法,organization_code_check.py来实现校验组织机构代码需求:
# -*- coding: utf-8 -*-
import string
CODEMAP = string.digits + string.ascii_uppercase # 用数字与大写字母拼接成CODEMAP,每个字符的index就是代表该字符的值
WMap = [3, 7, 9, 10, 5, 8, 4, 2] # 加权因子列表
def get_C9(bref):
# C9=11-MOD(∑Ci(i=1→8)×Wi,11)
# 通过本地计算出C9的值
sum = 0
for ind, i in enumerate(bref):
Ci = CODEMAP.index(i)
Wi = WMap[ind]
sum += Ci * Wi
C9 = 11 - (sum % 11)
if C9 == 10:
C9 = 'X'
elif C9 == 11:
C9 = '0'
return str(C9)
def check_organizationcode(code):
# 输入组织机构代码进行判断,如果正确,则输出'验证通过,组织机构代码证格式正确!',错误则返回错误原因
ERROR = '组织机构代码证错误!'
if '-' in code:
bref, C9_check = code.split('-')
else:
bref = code[:-1]
C9_check = code[-1:]
if len(bref) != 8 or len(C9_check) != 1:
return ERROR + '(本体或校验码长度不符合要求)'
else:
try:
C9_right = get_C9(bref)
except ValueError:
return ERROR + '(本体错误)'
if C9_check != C9_right:
return ERROR + '(校验码错误)'
else:
return '验证通过,组织机构代码证格式正确!'
if __name__ == '__main__':
print check_organizationcode('WV0X1KYT-X') # 正确
print check_organizationcode('WV0X1KYT5') # 正确
print check_organizationcode('WV0X1KYT-5') # 校验码错误
print check_organizationcode('WV0X1K-5') # 本体长度太短
print check_organizationcode('WV0X1KYT-50') # 校验码长度太长
print check_organizationcode('WV0X1KY@-5') # 本体中有特殊字符