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