import { toString } from 'ut2';
// 非0开头,10~21位数字
const reg = /^[1-9]\d{9,20}$/;
// 8~30位数字
const regLoose = /^\d{8,30}$/;
/**
* luhn 计算校验位
* @private
* @param {string} numStr 银行卡前面数字
* @returns {number}
*/
function sumCheckCode(numStr) {
const numArr = (numStr + '').replace(/\D/g, '').split('').reverse();
let sum = 0;
for (let i = 0; i < numArr.length; i++) {
const currNum = parseInt(numArr[i]);
sum += i % 2 === 0 ? currNum * 2 - (currNum > 4 ? 9 : 0) : currNum;
}
const mod = sum % 10;
return mod !== 0 ? 10 - mod : 0;
}
/**
* 检测值是否为银行卡号。正常模式(非0开头,10-21位数字)宽松模式(8-30位数字)
*
* @alias module:Validator.isBankCard
* @since 1.1.0
* @see {@link https://kf.qq.com/faq/170112ABnm6b170112FvquAn.html 常用银行账号位数参考}
* @param {*} value 要检测的值
* @param {Object} [options] 配置项
* @param {boolean} [options.loose=false] 宽松模式,默认`false`。正常模式10-21位数字(个人账户),宽松模式8-30位数字(企业账户)。
* @param {boolean} [options.luhn=false] 使用 Luhn 算法校验校验码,默认`false`
* @returns {boolean} 值是否为银行卡号
* @example
*
* isBankCard('6228480402564890018'); // true
* isBankCard('6228480402564890'); // true
* isBankCard('123456789'); // false
*
* // 宽松模式
* isBankCard('123456789', { loose: true }); // true
*
*/
function isBankCard(value, options = {}) {
const { loose = false, luhn = false } = options;
const valueStr = toString(value);
const validateResult = loose ? regLoose.test(valueStr) : reg.test(valueStr);
if (validateResult && luhn) {
const precode = valueStr.substring(0, valueStr.length - 1);
const checkCode = valueStr[valueStr.length - 1];
return checkCode === String(sumCheckCode(precode));
}
return validateResult;
}
export default isBankCard;