SOURCE

function validateTaxNo(taxNo) {
    if (!taxNo || taxNo.length !== 18) {
        return [false, '长度不正确']
    }
    taxNo = taxNo.toUpperCase()
    const chars = taxNo.split('')
    const c1 = chars[0]
    const c2 = chars[1]
    if (!/[1-9ANY]/.test(c1)) {
        return [false, '第一位登记部门代码不正确']
    } else {
        const tmpMap = {
            1: /^[1239]$/,
            2: /^[19]$/,
            3: /^[123459]$/,
            4: /^[19]$/,
            5: /^[1239]$/,
            6: /^[129]$/,
            7: /^[129]$/,
            8: /^[19]$/,
            9: /^[123]$/,
            A: /^[19]$/,
            N: /^[1239]$/,
            Y: /^1$/
        }
        if (!tmpMap[c1].test(c2)) {
            return [false, '第二位机构类别代码不正确']
        }
    }

    const code = chars.slice(8, 17).join('')
    let w = [3, 7, 9, 10, 5, 8, 4, 2]
    let sum = 0
    for (let i = 0; i < w.length; i++) {
        let val = code[i]
        if (/^[a-z]$/i.test(val)) {
            val = val.charCodeAt(0) - 'A'.charCodeAt(0) + 10
        } else if (/^\d$/.test(val)) {
            val = Number(val)
        }
        sum += val * w[i]
    }
    sum = sum % 11
    sum = 11 - sum
    if (sum == 10) {
        sum = 'X'
    } else if (sum == 11) {
        sum  = '0'
    } else {
        sum = sum + ''
    }
    if (code[8] !== sum) {
        return [false, '主体标识码校验不正确']
    }

    sum = 0
    w = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
    const charToNumberMap = {
        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
    }
    const numberToCharMap = Object.keys(charToNumberMap).reduce((prev, i) => {
        prev[charToNumberMap[i]] = i
        return prev
    }, {})
    for (let i = 0; i < chars.length - 1; i++) {
        let val = chars[i]
        if (/^[a-z]$/i.test(val)) {
            val = charToNumberMap[val]
        } else if (/^\d$/.test(val)) {
            val = Number(val)
        }
        sum += val * w[i]
    }
    sum = sum % 31
    sum = 31 - sum
    if (sum === 31) {
        sum = '0'
    } else if (sum >= 10) {
        sum = numberToCharMap[sum]
    } else {
        sum = sum + ''
    }
    if (chars[chars.length - 1] !== sum) {
        return [false, '最后一位校验码不正确']
    }
    return [true, undefined]
}

const [isValid, errMsg] = validateTaxNo('914404003348613293')
console.log(isValid, errMsg)
console 命令行工具 X clear

                    
>
console