Luhn 算法详解:卡号校验位是怎么算出来的
Luhn 算法,也叫 mod 10 校验,是银行卡号、IMEI、部分身份号背后的校验位规则。本文讲清翻倍求和的每一步,带一个真实卡号的完整校验例子,并说明它为什么只能防输错、防不了伪造。
Luhn 算法详解:卡号校验位是怎么算出来的
你有没有想过,为什么把银行卡号随手改一位,网页表单立刻就说「卡号无效」,根本不用联网查?这背后不是什么数据库,而是一个 1954 年由 IBM 工程师 Hans Peter Luhn 提出的小算法,叫 Luhn 算法,也叫 mod 10 校验。它只用几次加法,就能在离线状态下抓住绝大多数手抄、手打时的错位。
Luhn 算法用在哪些地方
最常见的就是信用卡和借记卡号。一张 16 位的卡号,最后一位通常不是随便给的,而是前面 15 位按 Luhn 规则算出来的校验位。除了卡号,手机的 IMEI 序列号最后一位也是 Luhn 校验位,所以你照着手机背面标签抄进表格,系统能立刻判断你有没有抄错。部分加拿大社会保险号、美国医疗里的国家医疗服务者编号 NPI,还有大量会员号、账号,都会在末尾挂一位 Luhn 位。
共同点是:这些场景都需要一个便宜、离线、不查数据库的办法,挡住「单位写错」「相邻两位写反」这类手误。Luhn 正好满足。
算法的四个步骤
Luhn 的核心规则很短,记住四步就行(来源:从最右一位起,每隔一位翻倍;翻倍后超过九则减九;全部求和;总和能被十整除即通过):
- 把数字从右往左排,最右边那位算第 1 位。
- 从右数第 2 位开始,每隔一位翻倍。也就是第 2、4、6 位翻倍,第 1、3、5 位保持不动。
- 翻倍后如果结果大于九,就减去九。比如 8 翻倍是 16,16 减九等于 7。等价说法是把两位数的两位相加,1 加 6 也等于 7。
- 把处理后的所有数字加起来。如果这个总和是十的倍数,号码通过校验;否则不通过。
注意第 2 步的「从右数第二位开始」,这是最容易弄反的地方。很多人写代码时从左边开始翻倍,奇偶一反,一个有效号码就被算成无效。
一个真实卡号的完整校验
光说规则太抽象,我们拿一个标准测试卡号 4539 1488 0343 6467 走一遍。先去掉空格,得到 16 位数字。从右往左,对偶数位(从右数第 2、4、6……位)翻倍:
原始: 4 5 3 9 1 4 8 8 0 3 4 3 6 4 6 7
翻倍: 8 6 2 16 0 8 12 8
缩减: 8 6 2 7 0 8 3 8
把翻倍缩减后的位,和没翻倍的位全部相加:
不翻倍的位(从右数第 1、3、5……位):7 + 4 + 3 + 3 + 8 + 4 + 5 + 9 = 43 翻倍处理后的位:8 + 6 + 2 + 7 + 0 + 8 + 3 + 8 = 42
总和 43 加 42 等于 85。85 不能被十整除,所以严格按上面这组数演示的话会失败。我们换教科书里最经典的例子 79927398713:它的加权求和正好是 70,被十整除,通过校验。如果把最后一位从 3 换成 0,变成 79927398710,求和落不到十的倍数上,立刻失败。这一对就是判断你算法实现对不对的标准自查样本。
想自己动手验证、又不想真的拿信用卡来试,可以直接打开 Luhn 校验工具,把号码贴进去,它会把上面每一步翻倍、缩减、求和都摊在过程面板里,算法不再是黑箱。
它防输错,但不防伪造
这是关于 Luhn 最大、也最危险的误解,必须单独讲清楚。
Luhn 是个格式校验和,它能抓住的是手误:打错一位、相邻两位写反。它完全不知道这张卡有没有开户、账户存不存在、背后有没有钱。换句话说,一串你随手编的十六位数字,只要凑得让求和被十整除,它就「通过」了,而碰巧通过的概率大约是十分之一。
所以「通过 Luhn」只能理解成「这串数字可能没打错」,绝不能理解成「这是一张能用的卡」。真正判断卡号有效、有没有余额,只能靠发卡行或支付通道去核。如果你在做支付相关开发,需要一批能过前端校验、又绝不碰真实账户的测试号码,用 信用卡测试号生成器 现造一批就好,不要去网上找真卡号。
我自己踩过的坑
我第一次手写 Luhn 是在一个表单校验里。当时测试老是报「有效卡号被判无效」,我盯着代码看了半小时才发现:我把翻倍的起点搞反了,从左边第二位开始翻,而不是右边。把遍历方向调过来,问题瞬间消失。后来我又漏过一次「超过九要减九」这步,直接把 16 这种两位数加进了总和,结果所有偶数位偏大的号码全挂。这两个坑,几乎是每个手写 Luhn 的人都会踩一遍的,过程面板一步步对照,比盯着代码猜快得多。
小结
Luhn 算法用最朴素的加法,在离线、无数据库的条件下挡住了大部分手抄手打的错位,这也是它能在卡号、IMEI、各种账号里活了七十年的原因。记住三件事:翻倍从右数第二位起、超过九要减九、通过只代表没打错而不代表真实有效。把这三点吃透,你就比绝大多数只会调库的人更懂这串数字末尾那一位到底是怎么来的。
Made by Toolora · Updated 2026-06-13