Luhn 算法
Luhn算法,也称为“模10”算法,是一种简单的校验算法,世界上大多数发卡机构,将该算法作为信用卡卡号的校验算法。能够通过该算法校验的卡号被认为是合规的卡号,但并不一定就是有效的卡号;无法通过验证的卡号,也不一定就是无效卡,这完全取决于发卡行是否使用该算法;有一点务必弄清楚,该算法的设计目的是防止意外输入错误,便于提前检查,而不是为了提供恶意攻击的工具。
一般信用卡由如下3部分组成:
- 6位发卡行识别号码(IIN),也称银行识别码(BIN)
- 最长12位的账户号码(Primary Account Number, PAN)
- 1位校验码,以Luhn算法计算
Luhn算法 会通过校验码对一串数字进行验证,校验码通常会被加到这串数字的末尾处,从而得到一个完整的身份识别码。
我们以数字“7992739871”为例,计算其校验位,设校验位为X并添加至数列末位,即7992739871X:
- 从校验位开始,从右往左,偶数位乘2(例如,7*2=14),然后将两位数字的个位与十位相加(例如,10:1+0=1,14:1+4=5);
- 把得到的数字加在一起(本例中得到67);
- 将数字的和取模10(本例中得到7),再用10去减(本例中得到3),得到校验位。
简单说来,该算法就是假设最后一位是校验位,然后从右到左,偶数位乘以2,将结果的个位和十位相加,
然后加上除开校验位之外所有奇数位,最终的和与10取模,然后用10减去该结果,其得的值应该等于校验位;如果不等,证明数字不符合该算法。
我们用 golang 来实现该算法:
func Luhn(creditCardCode string) bool {
s := []rune(creditCardCode)
if len(s) < 2 {
return false
}
sum := 0
for i, k := len(s)-1, 1; i >= 0; i, k = i-1, k+1 {
val, _ := strconv.Atoi(string(s[i]))
if k%2 == 0 {
adr := val * 2
a := adr / 10
b := adr % 10
sum = sum + (a + b)
} else {
if i < len(s)-1 {
sum = sum + val
}
}
}
checkCode := 10 - (sum % 10)
lastValue, _ := strconv.Atoi(string(s[len(s)-1]))
return checkCode == lastValue
}
Luhn算法 除了被用于信用卡校验外,还被用于验证 移动设备识别码(IMEI),加拿大社会保险号,和其他共有领域需要进行数字验证的地方。该算法由IBM科学家 Hans Peter Luhn 创造。