测试卡号与 Luhn 算法详解

你构建或测试过的每一个支付表单,在请求支付 API 之前都会默默执行同一个检查:Luhn 算法。这是一个诞生于 1954 年的单位校验和,能在请求离开浏览器之前拦截卡号中的绝大多数输入错误。理解它,你就明白了为什么测试数据生成器能产出通过表单校验的卡号——也明白了这些号码为什么完全"无效":它们无法扣款、没有资金、也不对应任何发卡银行。

本文将逐步讲解卡号的结构、Luhn 校验的完整演算过程、这个校验能验证什么与不能验证什么,以及如何在生成的测试卡号与支付平台(Stripe、PayPal、Adyen 等)官方发布的沙箱卡号之间正确分工。

银行卡号的结构

银行卡号并不是一串随机数字。前六到八位是发卡行识别码(IIN,常称 BIN),用于标识卡组织和发卡机构:以 4 开头的属于 Visa,51 到 55(以及较新的 2221–2720 区段)属于 Mastercard,34 或 37 开头的属于美国运通。正因为有这个前缀,结账表单才能在你输入头几位数字时就显示出正确的卡组织标志。

卡号长度因网络而异:Visa 和 Mastercard 通常为 16 位,Amex 为 15 位。IIN 之后的数字标识具体账户,而最后一位很特殊——它是校验位,由前面所有数字通过 Luhn 算法计算得出。只要改动其中任何一位数字,校验位就对不上了,这正是它存在的意义。

Luhn 校验的分步演算

这个算法简单到可以手算验证。从最右边的校验位开始向左走,每隔一位就把该位数字乘以 2;如果乘出两位数,就把两位数字相加——16 变成 7,18 变成 9。然后把所有数字(翻倍的和未翻倍的)加总,总和若能被 10 整除,卡号即通过校验。

用一个具体例子演算一遍。取数据段 7992739871,为它计算校验位。从右向左,处于翻倍位置的数字是 1、8、3、2、9,翻倍后得到 2、16、6、4、18,化简为 2、7、6、4、9,小计 28;未翻倍的数字 7、9、7、9、7 之和为 39,累计 67。校验位就是把总和补齐到下一个 10 的倍数所需的数字:这里是 3。于是完整的 Luhn 合法卡号是 79927398713。此后任何抄写错误——敲错一位数字,或大多数相邻两位的对调——都会破坏校验和。

支付表单为什么在前端做 Luhn 校验

Luhn 校验的存在是为了尽早拦下无心之失。手动输入卡号时,最常见的错误是敲错一位或相邻两位互换,而 Luhn 几乎能瞬间在浏览器里全部识别出来,无需一次网络请求。这意味着用户能更快得到反馈、注定失败的请求不会打到支付 API、"其实只是打错字"也不会变成一条令人困惑的拒付提示。

对开发者和 QA 来说,这层前端校验本身就是一个测试面:输入掩码、基于 IIN 前缀的卡组织识别、各网络的长度规则、Luhn 校验逻辑,都需要结构上"看起来正确"的测试输入。这正是生成的测试卡号的用武之地。

Luhn 不能验证什么

有必要把话说透:Luhn 只是格式校验,仅此而已。一个通过校验的号码,只说明这串数字在算术上自洽。它不代表存在对应的账户、不代表有任何银行发行过它、不代表背后有资金,更不代表能扣款成功。这个校验和与 CVV、有效期、持卡人姓名、账单地址也毫无关联——那些要由发卡银行在授权环节验证,而生成的号码永远走不到那一步。

这也是测试数据生成器产出的 Luhn 合法号码在其预期用途内天然安全的原因:它们只满足表单检查的那道算术,除此之外什么都没有。号码的另一端没有账户、没有余额、没有发卡行。

生成器如何产出 Luhn 合法的测试卡号

测试数据生成器不过是把算法倒着跑一遍:先选一个网络前缀——比如 Visa 风格的 4——再用随机数字填充中间各位,直到比目标长度少一位,然后对这段数据计算 Luhn 和,最后补上那个能让总和被 10 整除的校验位。对表单校验逻辑而言,结果在结构上与真实卡号无法区分,而这正是 UI 测试所需要的。

由于中间数字是随机的,这样的号码不与任何账户绑定。它能通过输入掩码和前端 Luhn 校验,但任何系统一旦尝试对它授权就会立刻被拒——没有发卡银行认识它,也没有任何东西可供扣款。

沙箱卡号、有效期与 CVV 测试数据

把两类测试工作划清界限。测试输入掩码、格式化、卡组织标志识别和前端校验时,生成的 Luhn 合法号码是正确工具;而任何触及支付 API 的环节——令牌化、授权、3-D Secure 流程、拒付、退款、Webhook——都必须使用支付平台官方发布的测试卡号。Stripe、PayPal、Adyen 都在开发者文档中维护了沙箱卡号列表,每个号码对应特定结果:扣款成功、余额不足拒付、触发验证挑战等。这些号码只在沙箱模式下生效,也是端到端验证支付集成的唯一正当方式。

卡号测试数据还需要合理的配套字段。正常路径的有效期应设在未来,同时至少准备一个过期日期来测试有效期校验;CVV 为三位随机数字(Amex 风格卡号为四位)。和卡号本身一样,生成的有效期和 CVV 不验证任何真实信息——它们的意义在于,让你在测试夹具中不含任何真实支付凭据的前提下,测完表单逻辑、错误状态和存储规则。

常见问题

生成的 Luhn 合法卡号能扣款吗? +

不能。通过 Luhn 校验只说明数字在算术上自洽。生成的号码没有发卡银行、没有账户、没有资金,任何授权尝试都会立即失败。它只适用于测试表单校验和 UI 行为。

为什么支付平台仍然会拒绝 Luhn 合法的号码? +

因为 Luhn 只是前端的第一道门。真正的授权要向卡组织和发卡银行确认账户是否存在、是否有效、是否有资金——生成的号码在这一步注定失败,这正是设计使然。API 层面的测试请使用平台文档中的官方沙箱测试卡号。

Stripe、PayPal、Adyen 的集成测试该用哪些卡号? +

使用这些平台在开发者文档中公布的测试卡号列表。每个沙箱号码都绑定特定场景——成功、拒付、3-D Secure 挑战——让集成测试结果可预期。生成的号码只应出现在前端测试和测试夹具里,不应出现在支付 API 调用中。

Luhn 算法会校验 CVV 或有效期吗? +

不会。校验和只覆盖卡号本身的数字。CVV 和有效期是独立字段,由发卡行在授权时验证,所以表单需要单独校验它们:有效期应在未来,CVV 为三位数字(Amex 格式为四位)。

最后更新: 2026-07-26

全部指南