生成银行卡号校验位和校验银行卡号

  • 大多数银行卡为16位或19位,所以只支持16位或19位的银行卡
  • 最后一位是校验位,银行卡校验规则基于Luhn算法
  • 以卡号6212280200141664948为例
  • 校验过程为:
    1. 去掉校验位 8,得621228020014166494
    2. 卡号倒数偶数位相加,即 9 + 6 + 1 + 1 + 0 + 0 + 2 + 1 + 6 = 26
    3. 卡号倒数奇数位分别乘以2,即 4、4、6、4、0、2、8、2、2分别乘以2,
      得 8、8、12、8、0、4、16、4、4
    4. 奇数位乘以2得到的如果是两位数,则个位和十位相加(或两位数减去9),否则不变,例如 12 -> 1 + 2, 16-> 16 - 9,分别得到 8、8、3、8、0、4、7、4、4
    5. 将奇数位的计算结果相加, 即 8 + 8 + 3 + 8 + 0 + 4 + 7 + 4 + 4 = 46
    6. 将偶数位的计算结果与奇数位的计算结果相加,即 26 + 46 = 72
    7. 计算结果乘以10,取模得 72 mod 10 = 2
    8. 如果模为0,则校验位为0,否则校验位为2的补位,即 10 - 2 = 8

Java算法

package com.xxx.demo.common.util;

import java.util.regex.Pattern;

public final class AcctIdUtils {
	
	private static final Pattern acctCheckPattern = Pattern.compile("^(?:\\d{16}|\\d{19})$");
	
	private static final Pattern acctCreatePattern = Pattern.compile("^(?:\\d{15,16}|\\d{18,19})$");
	
	private AcctIdUtils () {}
	
	/**
	 * 校验银行卡号是否合法
	 * @param acctId 16位银行卡号或19位银行卡号
	 * @return true,银行卡号是否合法;else false
	 */
	public static boolean checkAcctId(String acctId) {
		if (acctId == null || !acctCheckPattern.matcher(acctId).matches()) {
			return false;
		}
		return acctId.equals(createAcctId(acctId));
	}

	/**
	 * 根据银行卡号前面的数字,生成完整的卡号
	 * @param acctId 有效数字为16位银行卡号的前15位,或19位银行卡号的前18位
	 * @return 完整的卡号
	 */
	public static String createAcctId(String acctId) {
		if (acctId == null || !acctCreatePattern.matcher(acctId).matches()) {
			return "";
		}
		int sum = 0;
		int lastIndex = acctId.length() < 17 ? 14 : 17;
		String preAcctId = acctId.substring(0, lastIndex + 1);
		for (int i = 0; i <= lastIndex; i++) {
			int unit = acctId.charAt(lastIndex - i) - '0';
			if ((i & 1) == 0) {
				if (unit < 5) {
					sum += unit * 2;
				} else {
					sum += unit * 2 - 9;
				}
			} else {
				sum += unit;
			}
		}
		int remainder = sum % 10;
		int checkCode = remainder == 0 ? 0 : 10 - remainder;
		return preAcctId + checkCode;
		
	}

}

JavaScript算法

(function (window) {
    /**
     * 根据银行卡号前面的数字,生成完整的卡号
     * @param acctId 有效数字为16位银行卡号的前15位,或19位银行卡号的前18位
     * @return string 完整的卡号
     */
    var createAcctId = function (acctId) {
        if (!acctId || !/^(?:\d{15,16}|\d{18,19})$/g.test(acctId)) {
            return '';
        }
        acctId = '' + acctId;
        var sum = 0;
        var lastIndex = acctId.length < 17 ? 14 : 17;
        var preAcctId = acctId.substring(0, lastIndex + 1);
        for (var i = 0; i <= lastIndex; i++) {
            var unit = acctId.charAt(lastIndex - i) - '0';
            if ((i & 1) === 0) {
                if (unit < 5) {
                    sum += unit * 2;
                } else {
                    sum += unit * 2 - 9;
                }
            } else {
                sum += unit;
            }
        }
        var remainder = sum % 10;
        var checkCode = remainder === 0 ? 0 : 10 - remainder;
        return preAcctId + checkCode;
    };

    /**
     * 校验银行卡号是否合法
     * @param acctId 16位银行卡号或19位银行卡号
     * @return boolean true,银行卡号是否合法;else false
     */
    var checkAcctId = function (acctId) {
        if (!acctId || !/^(?:\d{16}|\d{19})$/g.test(acctId)) {
            return false;
        }
        acctId = '' + acctId;
        return acctId === createAcctId(acctId);
    };

    window.checkAcctId = checkAcctId;
    window.createAcctId = createAcctId;
})(window);

你可能感兴趣的:(java,前端,java,javascript,算法,js)