js银行卡号Luhn校验算法 js校验信用卡卡号实例详解

发布时间:2020-06-16编辑:脚本学堂
如何用js验证银行卡的有效性,js校验信用卡卡号真假的方法,在js中可以使用Luhn校验算法验证一个信用卡卡号是否正确,客户端校验信用卡的算法示例。

本节内容:
银行卡号校验的客户端校验算法

例1,Luhn校验算法校验信用卡卡号。
 

复制代码 代码示例:

//Create Time:  07/28/2011
//Operator: 刘政伟
//Description:  银行卡号Luhm校验

//Luhm校验规则:16位银行卡号(19位通用):

// 1.将未带校验位的 15(或18)位卡号从右依次编号 1 到 15(18),位于奇数位号上的数字乘以 2。
// 2.将奇位乘积的个十位全部相加,再加上所有偶数位上的数字。
// 3.将加法和加上校验位能被 10 整除。

//方法步骤很清晰,易理解,需要在页面引用jquery.js

//bankno为银行卡号 banknoInfo为显示提示信息的DIV或其他控件
function luhmCheck(bankno){
 var lastNum=bankno.substr(bankno.length-1,1);//取出最后一位(与luhm进行比较)

 var first15Num=bankno.substr(0,bankno.length-1);//前15或18位
 var newArr=new Array();
 for(var i=first15Num.length-1;i>-1;i--){//前15或18位倒序存进数组
 newArr.push(first15Num.substr(i,1));
 }
 var arrJiShu=new Array();  //奇数位*2的积 <9
 var arrJiShu2=new Array(); //奇数位*2的积 >9

 var arrOuShu=new Array();  //偶数位数组
 for(var j=0;j<newArr.length;j++){
 if((j+1)%2==1){//奇数位
  if(parseInt(newArr[j])*2<9)
  arrJiShu.push(parseInt(newArr[j])*2);
  else
  arrJiShu2.push(parseInt(newArr[j])*2);
 }
 else //偶数位
 arrOuShu.push(newArr[j]);
 }

 var jishu_child1=new Array();//奇数位*2 >9 的分割之后的数组个位数
 var jishu_child2=new Array();//奇数位*2 >9 的分割之后的数组十位数
 for(var h=0;h<arrJiShu2.length;h++){
 jishu_child1.push(parseInt(arrJiShu2[h])%10);
 jishu_child2.push(parseInt(arrJiShu2[h])/10);
 }

 var sumJiShu=0; //奇数位*2 < 9 的数组之和
 var sumOuShu=0; //偶数位数组之和
 var sumJiShuChild1=0; //奇数位*2 >9 的分割之后的数组个位数之和
 var sumJiShuChild2=0; //奇数位*2 >9 的分割之后的数组十位数之和
 var sumTotal=0;
 for(var m=0;m<arrJiShu.length;m++){
 sumJiShu=sumJiShu+parseInt(arrJiShu[m]);
 }

 for(var n=0;n<arrOuShu.length;n++){
 sumOuShu=sumOuShu+parseInt(arrOuShu[n]);
 }

 for(var p=0;p<jishu_child1.length;p++){
 sumJiShuChild1=sumJiShuChild1+parseInt(jishu_child1[p]);
 sumJiShuChild2=sumJiShuChild2+parseInt(jishu_child2[p]);
 } 
 //计算总和
 sumTotal=parseInt(sumJiShu)+parseInt(sumOuShu)+parseInt(sumJiShuChild1)+parseInt(sumJiShuChild2);

 //计算Luhm值
 var k= parseInt(sumTotal)%10==0?10:parseInt(sumTotal)%10;
 var luhm= 10-k;

 if(lastNum==luhm){
 $("#banknoInfo").html("Luhm验证通过");
 return true;
 }
 else{
 $("#banknoInfo").html("银行卡号必须符合Luhm校验");
 return false;
 }
}

LUHN是什么?

LUHN是一个算法,它的就要作用是为了计算信用卡等证件号码的合法性。我们用一个例子来看一下这个算法的工作过程:

假设我们有一个数4992 73 9871,这个数是没有带校验码的,算法的计算分为三步:

由最低位起每隔一位取一个数字,将这个数字乘2; 12=2 82=16 32=6 22=4 9*2=18 将数字中余下的数字和上面结果中的数字直接相加,得到结果B; 4 + 1+8 + 9 + 4 + 7 + 6 + 9 + 1+6 + 7 + 2 = 64 生成校验码C=A-B,其中A是比B大的10倍数中最小的数字,如B=86,则A=90;如B=34,A=40; 6 = 70-64 将校验码加在原来数字的后面生成合法的帐户密码; 4992 73 9871 6

银行卡校验规则(Luhn算法)

Luhn
检验数字算法(Luhn Check Digit Algorithm),也叫做模数10公式,是一种简单的算法,用于验证银行卡、信用卡号码的有效性的算法。对所有大型信用卡公司发行的信用卡都起作用,这些公司包括美国Express、护照、万事达卡、Discover和用餐者俱乐部等。这种算法最初是在20世纪60年代由一组数学家制定,现在Luhn检验数字算法属于大众,任何人都可以使用它。

算法:将每个奇数加倍和使它变为单个的数字,如果必要的话通过减去9和在每个偶数上加上这些值。如果此卡要有效,那么,结果必须是10的倍数。

比如上图的卡号为3759 8765 4321 001 (15位),从最高位开始所有的奇数位相加,偶数为乘以2相加(偶数乘以2后如果大于10则两位数相加),把这些奇数和偶数都加在一起得到57.

(57+3)%10 ==0 如果此卡满足被10整除,则有效位必定为3。

针对目前提现成功(clear_success)的记录里面,统计卡号的位数和数量关系如下:

卡号位数数量
<133038+
14538
15476
16   10884
1768
184395
19   38070
>20 504+

说明:
位数少于14的卡号基本是外资银行,或小银行。
***496748*** ** HSBC   HSBCHKHHHKH
***430259*** ** HSBC   HSBCHKHHHKH
***51878018*** **Bank of East Asia Limited  BEASHKHHXXX

位数多于23的卡号大多是卡号包含字母或空格。
62270014 **** 0045 ***  CHINA CONSTRUCTION BANK **
601382700 **** 9077 **  BANK OF CHINA FOSHAN BRANCH **

如果是国内的主流银行(中、农、工、建、招、交等)基本都是基于16位或者19位的卡号。

来看看提现成功(clear_success)里面的卡有多少满足Luhn规则

针对16位美元个人用户  准确率:99.84%

正确的卡号数量:3105不正确的卡号数量 :14

卡号45806509689007** is NOT valid

卡号48620375555016** is NOT valid

卡号54202100231152** is NOT valid

卡号58890201075786** is NOT valid

卡号62106200000456** is NOT valid

卡号62129986037235** is NOT valid

卡号62252017026526** is NOT valid

…..

针对19位美元个人用户   准确率:99.96%

正确的卡号数量:10574不正确的卡号数量 :13  其中3笔发生退票

卡号60138214000567721** is NOT valid

卡号60138217000662109** is NOT valid

卡号60138220005824282** is NOT valid

卡号60138220006014219** is NOT valid

卡号60220001386050410** is NOT valid

卡号62161132000004484** is NOT valid

卡号62220212082154900** is NOT valid

卡号62220836020035821** is NOT valid

卡号63214140980000000** is NOT valid

以上都是提现成功的卡号,可以看到基本都严格满足Luhn算法。

卡号位数数量
15  1
16  149
17  4
18  64
19  502
20  3

正确的卡号数量:622
不正确的卡号数量:29 + 1 +4+64+3

14%卡填写违法了Luhn算法,也就是这部分卡号都是可以提前通过Luhn校验发现的。

结论是我们可以在填写收款账户的时候,添加一种Luth算法的JS脚本检查用户填写的卡号存在问题。
当然即时用户填写的卡号违法了该规则,仍然运行用户填写,但给出相应的警示内容(可能填错)。

目前在收银台页面(Checkout.vm)针对信用卡的交易,校验的JS :isValidCardfunction函数就包含了Luth校验规则,必须严格按照该规则的卡才能提交表单

例2:
 

复制代码 代码示例:

/*
* accountNum : 存放银行卡帐号的字符串
* strLen : 银行卡帐号的字符串长度
* return  0 成功
*        -1 帐号出错
*/
int cheekLuhn(const char* accountNum, const int strLen)
{
int iRet = 0;
int i = 0;
int mark = 0;
int temp = 0;

while( i < strLen - 1 )
{
mark += accountNum[i];
i++;
temp = accountNum[i] * 2;
i++;
mark = temp / 10 + temp % 10;
}
if( accountNum[serLen - 1] != (10 - mark % 10) )
{
iRet = -1;
}
return iRet;
}