校验位是附加到数字末尾的额外数字,用于检测数据输入或传输中的错误。Luhn 算法(也称为 Mod 10)是最广泛使用的校验位方法——它内置于每个信用卡号、许多识别号码和 IMEI 代码中。理解它的工作原理对于从事支付系统工作的人员至关重要。
什么是校验位?
校验位是添加到数字中的单个数字,用于验证整个数字。如果有人输入错误的数字,校验位计算会立即失败,标记错误。
带校验位的数字示例:
- 信用卡号(所有主要网络)
- IMEI 号(移动设备标识符)
- ISBN 号(图书标识符)
- UPC/EAN 条形码(产品代码)
- 医疗保健中的国家提供者标识符(NPI)
Luhn 算法(Mod 10)
Luhn 算法由 IBM 的 Hans Peter Luhn 于 1954 年发明。它是一个简单的校验和公式,能检测大多数单位错误和许多换位错误。
分步过程
给定数字 7992739871:
步骤 1:从最右边的数字开始(不包括校验位)
位置: 1 2 3 4 5 6 7 8 9 10
数字: 7 9 9 2 7 3 9 8 7 1
步骤 2:从右到左每隔一个数字加倍
位置: 1 2 3 4 5 6 7 8 9 10
原始: 7 9 9 2 7 3 9 8 7 1
加倍: 7 18 9 4 7 6 9 16 7 2
步骤 3:如果加倍产生两位数,将这些数字相加
7 18→1+8=9 9 4 7 6 9 16→1+6=7 7 2
步骤 4:将所有数字相加
7 + 9 + 9 + 4 + 7 + 6 + 9 + 7 + 7 + 2 = 67
步骤 5:计算校验位
校验位 = (10 - (67 mod 10)) mod 10 = (10 - 7) mod 10 = 3
带校验位的完整数字是 79927398713。
验证数字
要验证,执行相同的计算(包括校验位)。如果总和 mod 10 等于 0,则数字有效:
7 + 9 + 9 + 4 + 7 + 6 + 9 + 7 + 7 + 2 + 3 = 70
70 mod 10 = 0 ✓ 有效
Luhn 能检测哪些错误?
| 错误类型 | 能检测? | 示例 |
|---|---|---|
| 单位错误 | 是 | 1234 → 1244 |
| 相邻数字换位 | 大部分 | 1234 → 1243 |
| 相同数字换位 | 部分 | 33 → 33(无错误) |
| 跳跃换位(第 1 和第 3 位) | 否 | 123 → 321 |
| 语音错误 | 否 | 180 → 190 |
Luhn 能检测大约 98% 的单位错误和大部分换位错误。
Luhn vs 其他校验位方法
Mod 10(Luhn)
- 支付系统中最常见
- Visa、Mastercard、American Express、Discover 使用
- 实现简单
- 良好的错误检测率
Mod 9
- 最简单的校验位方法
- 校验位 =(数字之和)mod 9
- 问题:无法区分 0 和 9 作为校验位
- 较少用于验证
Mod 11(ISBN-10)
- 用于 ISBN-10 号码
- 校验位可以是 0-9 或 X(表示 10)
- 比 Mod 10 更好的错误检测
- 计算更复杂
Verhoeff 算法
- 基于二面体群 D5
- 能检测所有单位错误和所有相邻换位错误
- 更复杂,用于某些身份证号
- 在支付系统中不太常见
信用卡号验证
卡号结构
信用卡号遵循 ISO/IEC 7812 标准:
前缀(IIN/BIN) + 账号 + 校验位
6 位数字 可变长度 1 位数字
| 卡网络 | 前缀 | 长度 |
|---|---|---|
| Visa | 4 | 16 |
| Mastercard | 51-55, 2221-2720 | 16 |
| American Express | 34, 37 | 15 |
| Discover | 6011, 65 | 16 |
| JCB | 35 | 16 |
| UnionPay | 62 | 16-19 |
验证过程
完整的信用卡验证检查:
- 长度:卡网络的正确位数
- 前缀:网络的有效 IIN/BIN
- Luhn:校验位通过 Luhn 验证
三项必须全部通过,数字才被视为有效。
IMEI 验证
IMEI(国际移动设备识别码)使用 Luhn 变体:
IMEI: 35-209900-176148-?
↑
TAC(类型分配码)
IMEI 是 15 位数字:14 位数字 + 1 位校验位。校验位使用 Luhn 算法对前 14 位数字计算。
IMEI 结构
| 部分 | 长度 | 描述 |
|---|---|---|
| TAC | 8 | 类型分配码(设备型号) |
| 序列号 | 6 | 设备序列号 |
| 校验位 | 1 | Luhn 校验位 |
ISBN 验证
ISBN-10 使用 Mod 11,不是 Luhn:
ISBN-10: 0-306-40615-?
位置: 1 2 3 4 5 6 7 8 9 10
权重: 10 9 8 7 6 5 4 3 2 1
总和 = 0×10 + 3×9 + 0×8 + 6×7 + 4×6 + 0×5 + 6×4 + 1×3 + 5×2 = 105
校验 = 105 mod 11 = 6
校验位: (11 - 6) mod 11 = 5
如果校验位计算结果为 10,则使用字符 X。
UPC/EAN 条形码验证
UPC-A(12 位)和 EAN-13(13 位)使用加权和方法:
UPC-A: 03600029145?
权重交替: 3, 1, 3, 1, ... (UPC-A)
1, 3, 1, 3, ... (EAN-13)
校验位 = (10 - (加权总和 mod 10)) mod 10
支付系统中的实际应用
POS 终端验证
当刷卡或插卡时:
- 从卡中读取 PAN
- 验证长度和前缀
- 执行 Luhn 检查
- 如果全部通过,继续授权
在线支付表单
JavaScript Luhn 验证提供即时反馈:
function luhnCheck(num) { let sum = 0; for (let i = num.length - 1; i >= 0; i--) { let digit = parseInt(num[i]); if ((num.length - i) % 2 === 0) { digit *= 2; if (digit > 9) digit -= 9; } sum += digit; } return sum % 10 === 0; }
测试卡号
支付处理商提供通过 Luhn 验证的测试卡号:
| 卡 | 卡号 | CVV |
|---|---|---|
| Visa | 4111111111111111 | 123 |
| Mastercard | 5500000000000004 | 123 |
| Amex | 378282246310005 | 1234 |
生成有效数字
为测试生成有效的信用卡号:
- 选择有效的前缀(例如,
4表示 Visa) - 为账号生成随机数字
- 计算 Luhn 校验位
- 附加校验位
这就是支付测试环境创建有效但虚构卡号的方式。
常见误解
"有效的 Luhn 检查意味着卡是真实的" — 不是。Luhn 仅验证格式。卡还必须存在于发卡机构的数据库中。
"Luhn 提供安全性" — 不是。Luhn 是错误检测算法,不是安全措施。生成 Luhn 有效数字非常简单。
"所有卡号都使用 Luhn" — 几乎所有现代支付卡都使用 Luhn,但某些遗留系统可能使用不同的方法。
在线工具
使用 校验位计算器:
- 计算和验证 Luhn(Mod 10)校验位
- 验证信用卡号、IMEI 号码等
- 理解 Luhn 计算的分步过程
- 生成用于开发的有效测试数字
所有处理都在浏览器中进行——您的数据永远不会离开您的设备。