UNPKG

uscc-utils

Version:

Utils about unified social credit code | 统一社会信用代码工具方法

278 lines (277 loc) 5.56 kB
//#region src/constants.ts /** * 正则 统一社会信用代码 * @see {@link https://www.wikidata.org/wiki/Property:P6795} * @see {@link https://regexper.com/#%2F%5B1-9ANY%5D%5B1-59%5D%5Cd%7B6%7D%5B%5CdA-Z%5D%7B8%7D%5B%5CdX%5D%5B%5CdA-HJ-NP-RTUW-Y%5D%2F} */ const USCC_PATTERN = /^[1-9ANY][1-59]\d{6}[\dA-Z]{8}[\dX][\dA-HJ-NP-RTUW-Y]$/u; /** * 登记管理部门代码 */ const USCC_CATEGORY_MAP = { 1: { category: "机构编制", map: { 1: "机关", 2: "事业单位", 3: "编办直接管理机构编制的群众团体", 9: "其他" } }, 2: { category: "外交", map: { 1: "外国常驻新闻机构", 9: "其他" } }, 3: { category: "司法行政", map: { 1: "律师执业机构", 2: "公证处", 3: "基层法律服务所", 4: "司法鉴定机构", 5: "仲裁委员会", 9: "其他" } }, 4: { category: "文化", map: { 1: "外国在华文化中心", 9: "其他" } }, 5: { category: "民政", map: { 1: "社会团体", 2: "民办非企业单位", 3: "基金会", 9: "其他" } }, 6: { category: "旅游", map: { 1: "外国旅游部门常驻代表机构", 2: "港澳台地区旅游部门常驻内地(大陆)代表机构", 9: "其他" } }, 7: { category: "宗教", map: { 1: "宗教活动场所", 2: "宗教院校", 9: "其他" } }, 8: { category: "工会", map: { 1: "基层工会", 9: "其他" } }, 9: { category: "工商", map: { 1: "企业", 2: "个体工商户", 3: "农民专业合作社" } }, A: { category: "中央军委改革和编制办公室", map: { 1: "军队事业单位", 9: "其他" } }, N: { category: "农业", map: { 1: "组级集体经济组织", 2: "村级集体经济组织", 3: "乡镇级集体经济组织", 9: "其他" } }, Y: { category: "其他", map: {} } }; //#endregion //#region src/validate.ts /** * 统一社会信用代码长度 */ const USCC_LENGTH = 18; /** * 统一社会信用代码 取模值 */ const USCC_MOD = 31; /** * 统一社会信用代码字符集 */ const USCC_CHARS = [ "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" ]; /** * 统一社会信用代码加权因子 */ const USCC_WEIGHTS = [ 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28 ]; /** * 标准化统一社会信用代码输入 * @param code - 原始统一社会信用代码 * @returns 标准化后的统一社会信用代码 */ function normalizeUSCC(code) { return code.trim().toUpperCase(); } function getCodeByOptions(code, options = {}) { const { normalize = false } = options; return normalize ? normalizeUSCC(code) : code; } /** * 获取统一社会信用代码的详细校验结果 * @param code - 统一社会信用代码 * @param options - 校验选项 * @returns 详细校验结果 */ function explainUSCC(code, options = {}) { const normalizedCode = getCodeByOptions(code, options); if (normalizedCode.length !== USCC_LENGTH) return { normalizedCode, isValid: false, errorCode: "INVALID_LENGTH" }; if (!USCC_PATTERN.test(normalizedCode)) return { normalizedCode, isValid: false, errorCode: "INVALID_PATTERN" }; if (!(USCC_CHARS[(USCC_MOD - [...normalizedCode].filter((_, idx) => idx < 17).reduce((acc, char, idx) => acc + USCC_CHARS.indexOf(char) * USCC_WEIGHTS[idx], 0) % USCC_MOD) % USCC_MOD] === normalizedCode.charAt(17))) return { normalizedCode, isValid: false, errorCode: "INVALID_CHECKSUM" }; return { normalizedCode, isValid: true }; } /** * 校验统一社会信用代码 * @param code - 统一社会信用代码 * @param options - 校验选项 * @returns 是否有效 * * @example * ``` * import { validateUSCC } from 'uscc-utils' * validateUSCC('91110108551385082Q') // true * ``` */ function validateUSCC(code, options = {}) { return explainUSCC(code, options).isValid; } /** * 按标准结构拆分统一社会信用代码 * @param code - 统一社会信用代码 * @param options - 校验选项 * @returns 若代码有效则返回结构化字段,否则返回 `null` */ function splitUSCC(code, options = {}) { const { isValid, normalizedCode } = explainUSCC(code, options); if (!isValid) return null; return { registrationAuthorityCode: normalizedCode.slice(0, 1), entityTypeCode: normalizedCode.slice(1, 2), regionCode: normalizedCode.slice(2, 8), organizationCode: normalizedCode.slice(8, 17), checkChar: normalizedCode.slice(17, 18) }; } //#endregion //#region src/parse.ts /** * 解析统一社会信用代码 * @param code - 待解析的统一社会信用代码 * @param options - 解析选项 * @returns 解析结果 `ParseResult` * * @example * ``` * import { parseUSCC } from 'uscc-utils' * parseUSCC('91110108551385082Q') // { isValid: true, category: '工商', type: '企业' } * ``` */ function parseUSCC(code, options = {}) { const { unknownCategory = "", unknownType = "", normalize = false } = options; const { isValid, normalizedCode } = explainUSCC(code, { normalize }); if (!isValid) return { isValid, category: unknownCategory, type: unknownType }; const matched = USCC_CATEGORY_MAP[normalizedCode.charAt(0)]; return { isValid, category: matched?.category ?? unknownCategory, type: matched?.map[normalizedCode.charAt(1)] ?? unknownType }; } //#endregion export { USCC_CATEGORY_MAP, USCC_PATTERN, explainUSCC, normalizeUSCC, parseUSCC, splitUSCC, validateUSCC };