使用方法
- 在「发卡行」里选一个品牌,它决定卡号开头的 6 位 IIN。默认 Visa,前缀是
4加 5 位随机数。 - 在「卡号长度」里选 13、15、16 或 19 位。每个品牌只接受固定几种长度:Visa 支持 13 / 16 / 19,Mastercard 只支持 16,American Express 只支持 15,UnionPay 与 Discover 支持 16 / 19,JCB 只支持 16;选错会给出具体提示。
- 在「生成数量」里填 1 到 50 之间的整数,默认 20。填非整数、0 或超过 50 都会被拦下并说明允许范围。
- 点「生成测试卡号」,或直接按 Enter(数量输入框支持裸 Enter)。结果表默认显示 12 行,点「加载更多」每次再加 12 行。
- 「复制全部」把当前表格内容按制表符复制到剪贴板,「导出 CSV」下载带 BOM 的文件,Excel 打开中文不乱码。分组显示按品牌习惯:16 位是 4-4-4-4,15 位是 4-6-5,19 位是 4-4-4-4-3,13 位是 4-4-5。
这个虚拟信用卡号生成器能解决什么
前端表单要验证卡号长度、分组展示和 Luhn 校验时,需要一批「格式正确但不真实」的号码作为测试数据,本页一次给 1 到 50 条。
后端要测 Luhn 实现写得对不对:拿固定 body 411111111111111 自测,正确实现算出的校验位应是 1,拼成 4111111111111111;如果你的实现给出别的数字,说明加倍起始位取错了。
要造不同发卡行的样本时,品牌前缀直接对应真实号段规则(Visa 4、万事达 51-55、运通 34/37、银联 62),前端按前缀判断卡组织图标的逻辑也能一起测到。
要估算号码空间时对照表给出了数字:16 位卡去掉 6 位 IIN 和 1 位校验位后剩 9 位随机,每个 IIN 下有 1 000 000 000 个可用号。
本页不做卡号的合法性校验——手里已有一个卡号想查它对不对,请交给银行卡号校验;也不生成礼品卡号(无 Luhn 校验的那类请用虚拟礼物卡号生成器),更不生成有效期和安全码,验证码请用虚拟CVV生成器。
原理与规则说明
虚拟信用卡号生成器的校验位用 Luhn 算法,也就是 ISO/IEC 7812-1 附录 B 定义的 mod 10 校验位算法。实现是一个从右往左的 for 循环:从 body 的最后一位开始,隔一位乘 2,乘积大于 9 就减 9,全部累加后取 (10 - sum % 10) % 10 作为校验位。中间位是 crypto.getRandomValues 从 Uint32Array 里取的。
倍率为什么取 2:乘 2 再减 9 在 0 到 18 的乘积范围内等价于取数字根,这让算法能检出全部单个数字写错的情况;换成 3 或其它倍率就没有这个性质。为什么减 9 而不是拆成十位加个位:实测在 0 到 18 上两种算法结果完全一致,减 9 少一次除法和一次加法,循环里省下来的量在批量生成时是可观的。
随机数为什么加拒绝采样:crypto.getRandomValues 给的是 32 位无符号整数,取值范围是 232 = 4 294 967 296。直接对 10 取模余 6,意味着 0 到 5 会各出现 429 496 730 次、6 到 9 各出现 429 496 729 次。虽然偏差只有 2.33×10-10,本页仍然在取到大于等于 4 294 967 290 时重抽,把偏差彻底消掉。
遵循的标准是 ISO/IEC 7812-1:一个 PAN 由 6 位 IIN、最多 12 位账户标识和 1 位校验位组成,总长不超过 19 位。ANSI X4.13 是同一算法的美国国标版本。PCI DSS 反过来要求生产环境展示或存储卡号时必须截断,所以本页生成的东西只应出现在测试库里。
输入到输出的完整链路:品牌 → 生成 6 位 IIN 前缀(Visa 是 4 加 5 位;万事达在 51-55 与 2221-2720 两套号段里二选一;运通是 34 或 37 加 4 位;银联是 62 加 4 位;JCB 是 3528 加 2 位;Discover 是 6011 加 2 位)→ 用拒绝采样补随机位直到长度减 1 → 对这串 body 跑 Luhn 得校验位 → 拼接成完整 PAN → 按品牌习惯分组显示。
完整示例(数值仅作演示)
以 body 411111111111111(15 位)为例逐位演示 Luhn:从最右的 1 开始加倍,得到 2;下一位不加倍,仍是 1;再下一位加倍……15 位全部处理完累加后,校验位算出来是 1,完整卡号 4111111111111111。
另外三个可对照的固定样本:550000555555555 的校验位是 9,340000000000009 的校验位是 1,621234567890123 的校验位是 2。把这三个 body 喂给你的实现,能对上说明加倍起始位和取模都写对了。
批量自检的结果:按本页算法随机生成 20 000 个 16 位号,Luhn 通过 20 000 个,通过率 100%。
首屏表格里 12 行是固定演示值(含 13、15、16、19 四种长度),也都是算出来的、全部通过校验;点「生成测试卡号」后会被新一批随机号码替换。
输入范围与对照表
| 发卡行 | IIN 前缀规则 | 允许长度 | 分组方式 | 每个 IIN 的号码空间 |
|---|---|---|---|---|
| Visa | 4 + 5 位随机 | 13 / 16 / 19 | 4-4-5 / 4-4-4-4 / 4-4-4-4-3 | 106 / 109 / 1012 |
| Mastercard | 51-55 或 2221-2720 | 16 | 4-4-4-4 | 109(1 000 000 000) |
| American Express | 34 或 37 + 4 位 | 15 | 4-6-5 | 108(100 000 000) |
| UnionPay | 62 + 4 位 | 16 / 19 | 4-4-4-4 / 4-4-4-4-3 | 109 / 1012 |
| JCB | 3528-3589 + 2 位 | 16 | 4-4-4-4 | 109 |
| Discover | 6011 或 65 + 4 位 | 16 / 19 | 4-4-4-4 / 4-4-4-4-3 | 109 / 1012 |
号码空间的计算口径是「总长 − 6 位 IIN − 1 位校验位」剩下的随机位数。16 位剩 9 位即 10 亿种,15 位剩 8 位即 1 亿种,19 位剩 12 位即 1 万亿种,13 位剩 6 位即 100 万种。
输入范围、边界与精度说明
长度只允许 13、15、16、19 四个值,且必须与品牌匹配。选 American Express 却选了 16 位会提示「American Express 的卡号长度固定为 15 位,当前选的是 16 位,请把长度改为 15 位」;Mastercard、JCB 同理只接受 16 位。这样限制是因为现实里这些品牌从不发行别的长度,造出来只会污染测试数据。
数量上限 50 条,下限 1 条。填 0、负数、小数或超过 50 都会被拦下并给出「生成数量请输入 1 到 50 之间的整数」这类具体文案,不会静默改成 1。
结果表默认渲染 12 行,数量填 20 时点一次「加载更多」显示全部 20 行;填 50 时需要再点两次。CSV 带 BOM 头,JSON 类导出才不能带 BOM,本页只有 CSV 一种导出格式。
虚拟信用卡号生成器全程不产生浮点中间量:校验位由整数取模得出,一定落在 0 到 9,不存在四舍五入误差。卡号全程按字符串处理,19 位数字如果交给 Number 会超过 253 安全整数上限(9 007 199 254 740 991)而丢精度,这也是本页不用数字类型存卡号的原因。
常见误用:把「通过 Luhn 校验」理解成「这是一张能用的卡」。Luhn 只是自洽性检查,不查发卡行是否存在、不查账户、不查余额。它甚至检不出所有相邻换位——实测 90 种相邻两位互换里有 2 种(09 与 90 互调)检不出来,占 2.2%,因为 9 加倍减 9 后仍是 9、0 加倍还是 0,总和不变。
常见问题
生成的号码能用来付款吗?
不能。它们只满足 Luhn 自洽和号段格式,没有对应账户也没有授权能力。真要跑通支付链路,请用收单机构或支付平台官方沙箱里给出的测试号与测试密钥。
为什么有些表单能通过、有些不能?
只检查长度和 Luhn 的前端校验会放行;接了发卡行白名单、BIN 表或 3-D Secure 的校验不会。这正说明它们不是真实卡号——本页也无法绕过任何一方的风控。
为什么要限制每个品牌的长度?
因为现实发卡行的长度是固定的:运通只有 15 位,万事达和 JCB 只有 16 位。生成 19 位的运通号会让你的测试数据与真实情况不符,反而掩盖 bug。
会不会生成到真实存在的卡号?
理论上有极小概率与某张真实卡号重合,所以本页结果只能放在测试环境,禁止写入任何生产库或用于任何交易尝试。号码空间最小也有 100 万种(13 位),一般表单测试足够。
有效期和 CVV 为什么不一起生成?
它们不属于 PAN 结构,也没有类似 Luhn 的公开校验算法,随机生成毫无意义。CVV 单独用虚拟CVV生成器。
每次生成的号码会重复吗?
同一批里中间位完全由 32 位加密随机数决定,16 位号有 10 亿种可能,实际重复概率可以忽略;但本页不做跨批次去重,如果你要一批互不相同的号,导出后自行检查。
生成的号码会被保存或上传吗?
不会。全部由浏览器本地的 crypto.getRandomValues 产生,没有任何网络请求;可以在开发者工具的 Network 面板确认,除页面自身 CSS 外不会再发请求。
为什么不是用数字类型而是字符串拼卡号?
19 位数字是 1.9×1018,远超 JavaScript 的安全整数上限 9 007 199 254 740 991,用 Number 存会丢掉末几位。全程字符串是唯一安全的做法。
相关工具
虚拟信用卡号生成器只负责「6 位 IIN + 随机位 + Luhn 校验位」这一件事,其它编号体系各有专门页面。