isSocialCreditCode.js

import { toString } from 'ut2';
// 基础规则,由18位数字和大写字母组成,不使用I、O、Z、S、V。
var baseReg = /^[\dA-HJ-NPQRTUWXY]{2}\d{6}[\dA-HJ-NPQRTUWXY]{10}$/;
// 基础字符组成
var baseCodeArr = '0123456789ABCDEFGHJKLMNPQRTUWXY'.split('');
/**
 * 计算校验码
 *
 * @private
 * @since 1.1.0
 * @param {string} preCode 统一代码前17位
 * @returns {string} 校验码
 */
function sumCheckCode(preCode) {
    var total = 0;
    var _loop_1 = function (i) {
        // 字符位置对应的基础编码序号
        var index = baseCodeArr.findIndex(function (item) { return item === preCode[i]; });
        // 加权因子
        var wf = Math.pow(3, i) % 31;
        // 计算序号和加权因子的乘积,并计算级数之和
        total += index * wf;
    };
    // 计算字符位置对应序号和加权因子的乘积,总和
    for (var i = 0; i < 17; i++) {
        _loop_1(i);
    }
    // 计算整数求余函数MOD
    var remainder = total % 31;
    // 校验码字符值序号
    var checkCodeIndex = remainder !== 0 ? 31 - remainder : 0;
    return baseCodeArr[checkCodeIndex];
}
/**
 * 检测值是否为统一社会信用代码,也叫三证合一组织代码。由18位数字和大写字母组成,不使用I、O、Z、S、V。
 *
 * @static
 * @alias module:Validator.isSocialCreditCode
 * @since 1.1.0
 * @see {@link https://zh.wikisource.org/zh-hans/GB_32100-2015_法人和其他组织统一社会信用代码编码规则 | GB 32100-2015 法人和其他组织统一社会信用代码编码规则}
 * @param {*} value 要检测的值
 * @param {Object} [options] 配置项
 * @param {boolean} [options.checkCode=true] 是否校验最后一位校验码,如果为false,不校验校验位。
 * @returns {boolean} 值是否为统一社会信用代码
 * @example
 *
 * isSocialCreditCode('91350100M000100Y43'); // true
 * isSocialCreditCode('91350100M000100Y4A'); // false
 *
 * // 不校验校验位,长度和类型还是有校验的
 * isSocialCreditCode('91350100M000100Y4A', { checkCode: false }); // true
 * isSocialCreditCode('91350100M000100YIO', { checkCode: false }); // false
 * isSocialCreditCode('91350100M000100Y', { checkCode: false }); // false
 *
 */
function isSocialCreditCode(value, options) {
    if (options === void 0) { options = {}; }
    var valueStr = toString(value);
    var _a = options.loose, loose = _a === void 0 ? false : _a, _b = options.checkCode, cc = _b === void 0 ? true : _b;
    var needCheckCode = !loose && cc;
    var passBaseRule = baseReg.test(valueStr);
    // 宽松模式 或 基础规则不通过直接返回
    if (!needCheckCode || !passBaseRule) {
        return passBaseRule;
    }
    // 前17位
    var preCode = valueStr.substring(0, 17);
    // 校验码
    var lastCode = valueStr.substring(valueStr.length - 1);
    // 计算校验码
    var checkCode = sumCheckCode(preCode);
    return lastCode === checkCode;
}
export default isSocialCreditCode;