简介
卢恩算法(Luhn Algorithm),也称为模10算法(Mod 10 Algorithm),是由IBM科学家Hans Peter Luhn在1954年提出的一种简单校验和算法,主要用于验证各种数字标识符的有效性,如:
- 信用卡号(Visa、MasterCard、American Express等)
- IMEI(国际移动设备识别码),例如我的IMEI是867238058873512
- SIM卡的唯一标识ICCID
- 注意:身份证最后一位并不是卢恩校验,但也是用了类似的校验算法,后续再单独介绍。
算法原理
卢恩算法的核心思想是通过对数字进行加权计算,并检查最终结果是否能被10整除,从而判断数字是否有效。
计算步骤
1.从右到左,对每隔一位乘以2(从最右边的第二个数字开始乘以2); 2.如果乘以2后的数字大于9,则减去9(或拆分成个位+十位相加); 3.将所有数字相加,得到总和; 4.检查总和是否能被10整除:
如果 总和 % 10 == 0,则该数字有效。 否则,该数字无效。
示例
假设我们要验证信用卡号 7992 7398 713(最后一位是校验位): 步骤1:从右到左,每隔一位乘以2
| 原始数字 | 7 | 9 | 9 | 2 | 7 | 3 | 9 | 8 | 7 | 1 | 3 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 位置 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
| 计算方式 | ×1 | ×2 | ×1 | ×2 | ×1 | ×2 | ×1 | ×2 | ×1 | ×2 | ×1 |
| 计算后 | 7 | 18 | 9 | 4 | 7 | 6 | 9 | 16 | 7 | 2 | 3 |
步骤2:处理大于9的数字(拆分成个位+十位) 18 → 1 + 8 = 9 16 → 1 + 6 = 7 更新后的数字: | 数字 | 7 | 9 | 9 | 4 | 7 | 6 | 9 | 7 | 7 | 2 | 3 |
步骤3:计算总和 7 + 9 + 9 + 4 + 7 + 6 + 9 + 7 + 7 + 2 + 3 = 70
步骤4:检查是否能被10整除 70 % 10 == 0 → 有效
代码实现
Python 实现
def luhn_checksum(card_number):
digits = [int(d) for d in str(card_number)]
odd_digits = digits[-1::-2] # 从右到左的奇数位(第1、3、5...位)
even_digits = digits[-2::-2] # 从右到左的偶数位(第2、4、6...位)
checksum = sum(odd_digits)
for d in even_digits:
checksum += sum(divmod(d * 2, 10)) # 如果d*2>=10,则拆分成1+(d*2-10)
return checksum % 10 == 0
# 示例
card_number = "79927398713"
print(luhn_checksum(card_number)) # True
给出一串数字,计算其卢恩位:
def calculate_luhn_check_digit(number_str):
total = 0
# 从右往左处理每一位(不包括校验位)
for i, ch in enumerate(reversed(number_str)):
digit = int(ch)
# 偶数位(从0开始计数)需要×2
if i % 2 == 0:
digit *= 2
if digit > 9:
digit -= 9
total += digit
return (10 - (total % 10)) % 10
# 示例
number = "7992739871"
check_digit = calculate_luhn_check_digit(number)
print(f"校验位是: {check_digit}") # 输出3
print(f"完整号码: {number}{check_digit}") # 输出79927398713
总结
- 计算时是从右往左数(校验位是第1位,它左边的是第2位)
- 最终校验位要使总和能被10整除
- 模10操作确保当总和已经是10的倍数时,校验位为0
在线卢恩算法计算器
本人在个人网站开发了一个在线的卢恩校验计算器,有兴趣可以试试。 在线卢恩校验计算器