java实现银行卡号校验算法luhn

    Luhn是著名的校验和算法也叫模10算法,主要应用于解决银行卡号,社保号等重要信息传输出错问题。

    先来解释下算法原理,校验和类型的算法,一般是ID+校验号,校验号和ID号的每位相关,如果出错,通过某种运算能检测出这种改动。借用维基百科的例子我来解释下。

    我们以数字“7992739871”为例,计算其校验位:

  1. 从校验位开始,从右往左,偶数位乘2(例如,7*2=14),然后将两位数字的个位与十位相加(例如,10:1+0=1,14:1+4=5);
  2. 把得到的数字加在一起(本例中得到67);
  3. 将数字的和取模10(本例中得到7),再用10去减(本例中得到3),得到校验位。
原始数字7992739871x
偶数位乘2718947691672x
将数字相加7994769772=67

    OK,解释到这里,那么跟我们有什么相关呢,最常见的例子就是银行卡号,我们的银行卡号其实最后一位都是由该算法得出的校验码,校验码不用我们算了,我们只要从低位向高位(包括校验和),偶数位做上述转化,然后每位加在一起,必然满足%10==0,否则校验失败,下面是我实现的Luhn类,主要功能是校验和生成校验码。

public class Luhn {
	private int[] no;
	
	private Boolean isValidate = null;

	public Luhn(String strno)
	{
		this(convertStrToInArr(strno));
	}
	public Luhn(int[] no)
	{
		if(null!=no && no.length>0)
		{
			this.no = Arrays.copyOf(no, no.length);
			for(int i=0;i<no.length;i++)
			{
				if(no[i]<0)
				{
					throw new IllegalArgumentException("No can not contain negtive value");
				}
			}
		}else{
			throw new IllegalArgumentException("No is null or Empty");
		}
	}
	/**
	 * 校验
	 * @return
	 */
	public boolean check()
	{
		if(null == isValidate)
		{
			isValidate = luhnCheck(getCardNoArr());
		}
		return isValidate;
	}
	/**
	 * 获取全部id
	 * @return
	 */
	public int[] getCardNoArr()
	{
		return Arrays.copyOf(no, no.length);
	}
	/**
	 * 计算校验和的算法
	 * @return
	 */
	public int getCheckSum(){
		if(check())
		{
			return no[0];
		}
		int[] cardNoArr = getCardNoArr();
		for(int i=0;i<cardNoArr.length;i+=2)
		{
			cardNoArr[i] <<= 1;
			cardNoArr[i] = cardNoArr[i]/10 + cardNoArr[i]%10;
		}
		int sum = 0;
		for(int i=0;i<cardNoArr.length;i++)
		{
			sum += cardNoArr[i];
			//System.out.print(cardNoArr[i]);
		}
		return sum * 9 % 10;
	}
	
	private static int[] convertStrToInArr(String cardNo) {
		if(null==cardNo)throw new IllegalArgumentException();
		int index = cardNo.length();
		int[] cardNoArr = new int[cardNo.length()];
		for(char c : cardNo.toCharArray())
		{
			cardNoArr[--index] = c - '0';
		}
		return cardNoArr;
	}
	/**
	 * 校验的具体算法实现
	 * @param cardNoArr
	 * @return
	 */
	private static boolean luhnCheck(int[] cardNoArr) {
		for(int i=1;i<cardNoArr.length;i+=2)
		{
			cardNoArr[i] <<= 1;
			cardNoArr[i] = cardNoArr[i]/10 + cardNoArr[i]%10;
		}
		int sum = 0;
		for(int i=0;i<cardNoArr.length;i++)
		{
			sum += cardNoArr[i];
			//System.out.print(cardNoArr[i]);
		}
		
		return sum % 10 == 0;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值