Created
October 27, 2021 15:59
-
-
Save KaiserKatze/7e442409638d8f45eeef6e4689b0e99f to your computer and use it in GitHub Desktop.
统一社会信用代码
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# 参照《GB 11714-1997》《GB 32100-2015》两个标准文件 | |
class BaseCode(str): | |
MAX_LENGTH: int | |
def __new__(cls, *args, **kwargs): | |
_s = str.__new__(cls, *args, **kwargs) | |
if len(_s) != cls.MAX_LENGTH: | |
raise ValueError("Invalid str length!") | |
return _s | |
class OrgCode(BaseCode): # 组织机构代码 | |
MAX_LENGTH = 9 | |
weight = [3, 7, 9, 10, 5, 8, 4, 2] | |
@staticmethod | |
def cvt_char2int(c: str) -> int: | |
c = ord(c) | |
if ord('0') <= c <= ord('9'): | |
return c - ord('0') | |
elif ord('A') <= c <= ord('Z'): | |
return c - ord('A') + 10 | |
else: | |
raise AssertionError(u"非法组织机构代码!") | |
def calc_checksum(self): | |
cs = 11 - (sum([ | |
self.cvt_char2int(c) * self.weight[i] | |
for i, c in enumerate(self[:8]) | |
]) % 11) | |
return { | |
1: 'X', | |
}.get(cs, str(cs)) | |
@property | |
def checksum(self): | |
return self[8] | |
def validate(self): | |
return self.checksum == self.calc_checksum() | |
class UniversalCode(BaseCode): # 统一社会信用代码 | |
MAX_LENGTH = 18 | |
@staticmethod | |
def cvt_char2int(c: str) -> int: | |
return { | |
'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, | |
}[c] | |
@staticmethod | |
def cvt_int2char(c: int) -> str: | |
return { | |
0: '0', | |
1: '1', | |
2: '2', | |
3: '3', | |
4: '4', | |
5: '5', | |
6: '6', | |
7: '7', | |
8: '8', | |
9: '9', | |
10: 'A', | |
11: 'B', | |
12: 'C', | |
13: 'D', | |
14: 'E', | |
15: 'F', | |
16: 'G', | |
17: 'H', | |
18: 'J', | |
19: 'K', | |
20: 'L', | |
21: 'M', | |
22: 'N', | |
23: 'P', | |
24: 'Q', | |
25: 'R', | |
26: 'T', | |
27: 'U', | |
28: 'W', | |
29: 'X', | |
30: 'Y', | |
}[c] | |
@property | |
def reg_admin(self): | |
return self[0] | |
@property | |
def org_category(self): | |
return self[1] | |
@property | |
def reg_area(self): | |
return self[2:8] | |
@property | |
def org_code(self): | |
return OrgCode(self[8:17]) | |
@property | |
def checksum(self): | |
return self[17] | |
@property | |
def reg_admin_s(self): | |
try: | |
return { | |
'1': u"机构编制", | |
'5': u"民政", | |
'9': u"工商", | |
'Y': u"其他", | |
}[self.reg_admin] | |
except KeyError: | |
raise AssertionError(u"未知登记管理部门代码【{}】!".format(self.reg_admin)) | |
@property | |
def org_category_s(self): | |
try: | |
return { | |
'1': { | |
'1': u"机关", | |
'2': u"事业单位", | |
'3': u"中央编办直接管理机构编制的群众团体", | |
'9': u"其他", | |
}, | |
'5': { | |
'1': u"社会团体", | |
'2': u"民办非企业单位", | |
'3': u"基金会", | |
'9': u"其他", | |
}, | |
'9': { | |
'1': u"企业", | |
'2': u"个体工商户", | |
'3': u"农民专业合作社", | |
}, | |
'Y': { | |
'1': u"" | |
}, | |
}[self.reg_admin][self.org_category] | |
except KeyError: | |
raise AssertionError(u"未知机构类别代码【{}-{}】!".format(self.reg_admin, self.org_category)) | |
def calc_checksum(self): | |
cs = 31 - (sum([ | |
self.cvt_char2int(c) * (3 ** i % 31) | |
for i, c in enumerate(self[:17]) | |
]) % 31) | |
return { | |
31: '0', | |
}.get(cs, self.cvt_int2char(cs)) | |
def validate(self): | |
return self.org_code.validate() and self.checksum == self.calc_checksum() | |
if __name__ == "__main__": | |
s = input(u"请输入统一社会信用代码:") | |
uc = UniversalCode(s) | |
print("验证结果:", u"正确" if uc.validate() else u"错误") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment