先看一下mod10算法的描述:
计算的规则:
1 Beginning on the right, with the digit that immediately precedes the check digit and moving toward the left, double every other digit. After doubling each selected digit, if the result is ten or greater, add the two digits together to arrive at a single-digit result.
4012 8888 8888 1881
[8]0[2]2 [16]8[16]8 [16]8[16]8 [2]8[16]1
8022 7878 7878 2871
2 Each individual resulting digit, plus those bypassed, above is then added together.
8022 7878 7878 2871
8+0+2+2+7+8+7+8+7+8+7+8+2+8+7+1
= 90
3 This sum is then subtracted from the lowest multiple of ten that is equal to or greater than the sum, and the single-digit result is the check digit.
90 ÷ 10 = 9
90 Mod 10 = 0
简单的讲就是从号码后面的最后一位乘以1算起,然后上一位的2倍,2倍后大于9这则减去9或者十位和各位相加。最后把这些的和对10进行取模,看是否是0,然后进行决定是否是信用卡号:
网上有找到两段代码,一段是c的,一段时JavaScript的,c的写的比较巧。
1 :
int LuhnMod10(char* cardNumber, int size)
{
static int table[10] = { {0,1,2,3,4,5,6,7,8,9}, {0,2,4,6,8,1,3,5,7,9} };
for (int i=size-1, odd=0, sum=0; i>=0; i--)
if (isdigit(cardNumber[i]))
sum += table[(odd=1-odd)][cardNumber[
<div id=":s8">i]-'0'];
sum %= 10;
return (sum ? 10-sum : 0); /* return the check digit *
}
</div>
js的的则相当繁琐,如果读懂了两段代码,可以看到上面用c写的之妙,之美:
function Mod10(ccNumb) { // v2.0
var valid = “0123456789″ // Valid digits in a credit card number
var len = ccNumb.length; // The length of the submitted cc number
var iCCN = parseInt(ccNumb); // integer of ccNumb
var sCCN = ccNumb.toString(); // string of ccNumb
sCCN = sCCN.replace (/^\s+|\s+$/g,”); // strip spaces
var iTotal = 0; // integer total set at zero
var bNum = true; // by default assume it is a number
var bResult = false; // by default assume it is NOT a valid cc
var temp; // temp variable for parsing string
var calc; // used for calculation of each digit
// Determine if the ccNumb is in fact all numbers
for (var j=0; j<len; j++) {
temp = “” + sCCN.substring(j, j+1);
if (valid.indexOf(temp) == “-1″){bNum = false;}
}
// if it is NOT a number, you can either alert to the fact, or just pass a failure
if(!bNum){
/*alert(”Not a Number”);*/bResult = false;
}
// Determine if it is the proper length
if((len == 0)&&(bResult)){ // nothing, field is blank AND passed above # check
bResult = false;
} else{ // ccNumb is a number and the proper length – let’s see if it is a valid card number
if(len >= 15){ // 15 or 16 for Amex or V/MC
for(var i=len;i>0;i–){ // LOOP throught the digits of the card
calc = parseInt(iCCN) % 10; // right most digit
calc = parseInt(calc); // assure it is an integer
iTotal += calc; // running total of the card number as we loop – Do Nothing to first digit
i–; // decrement the count – move to the next digit in the card
iCCN = iCCN / 10;
// subtracts right most digit from ccNumb
calc = parseInt(iCCN) % 10 ; // NEXT right most digit
calc = calc *2; // multiply the digit by two
// Instead of some screwy method of converting 16 to a string and then parsing 1 and 6 and then adding them to make 7,
// I use a simple switch statement to change the value of calc2 to 7 if 16 is the multiple.
switch(calc){
case 10: calc = 1; break; //5*2=10 & 1+0 = 1
case 12: calc = 3; break; //6*2=12 & 1+2 = 3
case 14: calc = 5; break; //7*2=14 & 1+4 = 5
case 16: calc = 7; break; //8*2=16 & 1+6 = 7
case 18: calc = 9; break; //9*2=18 & 1+8 = 9
default: calc = calc; //4*2= 8 & 8 = 8 -same for all lower numbers
}
iCCN = iCCN / 10; // subtracts right most digit from ccNum
iTotal += calc; // running total of the card number as we loop
} // END OF LOOP
if ((iTotal%10)==0){ // check to see if the sum Mod 10 is zero
bResult = true; // This IS (or could be) a valid credit card number.
} else {
bResult = false; // This could NOT be a valid credit card number
}
}
}
// change alert to on-page display or other indication as needed.
if(bResult) {
alert(”This IS a valid Credit Card Number!”);
}
if(!bResult){
alert(”This is NOT a valid Credit Card Number!”);
}
return bResult; // Return the results
}
// –>
</script>
摘自:http://www.techrss.cn/html/2008/10-20/152593.htm