util-helpers 4.8.0 → 4.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -316,6 +316,24 @@
316
316
  // 8~30位数字
317
317
  const regLoose = /^\d{8,30}$/;
318
318
 
319
+ /**
320
+ * luhn 计算校验位
321
+ *
322
+ * @param {string} num 银行卡前面数字
323
+ * @returns
324
+ */
325
+ function sumCheckCode$2(num) {
326
+ const numArr = (num + '').replace(/\D/g, '').split('').reverse();
327
+
328
+ let sum = 0;
329
+ for (let i = 0; i < numArr.length; i++) {
330
+ const currNum = parseInt(numArr[i]);
331
+ sum += i % 2 === 0 ? currNum * 2 - (currNum > 4 ? 9 : 0) : currNum;
332
+ }
333
+ const mod = sum % 10;
334
+ return mod !== 0 ? 10 - mod : 0;
335
+ }
336
+
319
337
  /**
320
338
  * 检测值是否为银行卡号。正常模式(非0开头,10~21位数字)宽松模式(8~30位数字)
321
339
  *
@@ -326,6 +344,7 @@
326
344
  * @param {*} value 要检测的值
327
345
  * @param {Object} [options] 配置项
328
346
  * @param {boolean} [options.loose=false] 宽松模式,8~30位数字
347
+ * @param {boolean} [options.luhn=false] 使用 Luhn 算法校验校验码
329
348
  * @returns {boolean} 值是否为银行卡号
330
349
  * @example
331
350
  *
@@ -342,13 +361,16 @@
342
361
  * // => true
343
362
  *
344
363
  */
345
- function isBankCard(value, { loose = false } = {}) {
364
+ function isBankCard(value, { loose = false, luhn = false } = {}) {
346
365
  const valueStr = convertToString(value);
366
+ const validateResult = loose ? regLoose.test(valueStr) : reg$5.test(valueStr);
347
367
 
348
- if (loose) {
349
- return regLoose.test(valueStr);
368
+ if (validateResult && luhn) {
369
+ const precode = valueStr.substring(0, valueStr.length - 1);
370
+ const checkCode = valueStr[valueStr.length - 1];
371
+ return checkCode === String(sumCheckCode$2(precode));
350
372
  }
351
- return reg$5.test(valueStr);
373
+ return validateResult;
352
374
  }
353
375
 
354
376
  // 基础规则,由18位数字和大写字母组成,不使用I、O、Z、S、V。
@@ -357,28 +379,6 @@
357
379
  // 基础字符组成
358
380
  const baseCodeArr = '0123456789ABCDEFGHJKLMNPQRTUWXY'.split('');
359
381
 
360
- /**
361
- * 获取字符位置
362
- *
363
- * @private
364
- * @param {string} code 字符
365
- * @returns {number} 字符所在基础字符的位置
366
- */
367
- function getBaseCodeIndex(code) {
368
- let ret;
369
-
370
- baseCodeArr.some((item, index) => {
371
- if (item === code) {
372
- ret = index;
373
- return true;
374
- }
375
- return false;
376
- });
377
-
378
- // @ts-ignore
379
- return ret;
380
- }
381
-
382
382
  /**
383
383
  * 计算校验码
384
384
  *
@@ -388,14 +388,12 @@
388
388
  * @returns {string} 校验码
389
389
  */
390
390
  function sumCheckCode$1(preCode) {
391
- // const preCodeArr = preCode.split('');
392
-
393
391
  let total = 0;
394
392
 
395
393
  // 计算字符位置对应序号和加权因子的乘积,总和
396
394
  for (let i = 0; i < 17; i++) {
397
395
  // 字符位置对应的基础编码序号
398
- const index = getBaseCodeIndex(preCode[i]);
396
+ const index = baseCodeArr.findIndex((item) => item === preCode[i]);
399
397
  // 加权因子
400
398
  const wf = Math.pow(3, i) % 31;
401
399
  // 计算序号和加权因子的乘积,并计算级数之和