菜单

信用卡号格式:发卡行识别号、账户位与校验位

信用卡号格式由发卡行识别号、账户位和校验位三段构成,不同卡组织的长度并不相同。本文逐段解释每一部分的作用,并说明号码变长变短各意味着什么。

发布于

  • 卡号规则
  • 测试数据

把卡号当成十六个互不相关的随机数字,是很多人接触支付系统时最早的误解。信用卡号格式其实被精心分段:开头的几位说明这串数字由哪家卡组织处理,中间部分对应某一个具体账户,最后一位负责证明前面的部分没有抄错。看清这三段各管什么,很多「这个号码为什么被拒绝」的问题都能当场回答。

这篇文章不谈算法实现,只谈怎么读。读完你会知道为什么 16 位不是唯一合法的长度,也能自己判断一段数字落在哪家卡组织的号段里。

号码的三段结构

按照公开的编号方案,一个卡号由三部分依次拼成:

  • 发卡行识别号:位于号码最前端,长度可以是若干位,用来标识发卡机构与卡组织。它在公开的编号方案里有明确规定,因此同一个区间的号码会落在同一家卡组织名下。旧称发卡行标识号,现在通称发卡行识别号。
  • 账户数字:中间的部分,由发卡行自行分配。它的长度不是固定的,而是「总长度减去其余两段」剩下的位数。
  • 校验位:最后一位,由前面所有数字按模 10 规则反推出来,用途是发现录入错误。

这三段里,前两段是「内容」,最后一段是「冗余」。冗余的存在与否,是判断一串数字是否被设计成卡号的最快线索。

哪些长度才是合法的?

合法的长度不是一种,而是一组。很多人以为卡号必须是 16 位,其实公开规范给的上限是 19 位,而市面上常见的长度就至少有 13、14、15、16 位几种。差异来自历史:

早期的编号方案并没有统一的总长度要求,各家卡组织按当时的业务规模自行决定。发卡量大的卡组织后来扩容过,于是同一家卡组织内部也可能出现两种长度并存的情况。旅行娱乐类的卡组织选用 15 位,是因为它早年定下的规则一直保留到现在。

这件事对开发者的直接含义是:把长度写死成 16 位,一定会误伤一部分合法输入。正确的做法是按首位数字识别卡组织,再套用该卡组织允许的长度集合。

还有一层更细的差异:账户数字那一段本身也不是定长的。有些编号方案允许发卡行自行分配这段的位数,于是同一家卡组织可以同时存在两种总长度。这也是为什么以长度作为第一道筛选条件时,只能用它排除明显错误的输入,而不能用它反推卡组织。凡是「看到 15 位就一定是某一家」这类推断,早晚会遇到反例。

开头的数字在说什么

号码的首位数字是一层更粗略的分类,它在公开方案里代表行业归属。把它记成一张表,比死记每个卡组织的前缀更省事:

首位 行业归属 常见例子
4、5 银行与金融卡 Visa、Mastercard
3 旅行与娱乐 American Express、Diners Club、JCB
6 商业与银行 Discover、银联
2、1 航空业 航空业专用编号
7 石油业 加油卡
8 电信业 通信行业编号
9 国家分配 各国自行规定的用途

这张表是公开的编号方案,不是秘密。知道它能帮你快速判断一串数字「像不像」卡号,但它证明不了这串数字对应任何账户。

前六位和后四位有什么特别?

在支付行业里,你经常会看到只显示前六位与后四位的号码,中间用星号代替。这不是随意的装饰,而是有明确来源的展示约定。

前六位是发卡行识别号最常见的长度,它足够让客服或对账系统判断这是哪家卡组织、哪种卡产品;后四位则给了持卡人一个可核对的尾巴,让人能确认「这是我那张卡」。中间被隐去的部分才是账户数字的主体,它属于敏感信息。

顺带说明一个容易混淆的点:号码中间那组数字与安全码完全无关。安全码是独立印刷的,无法从卡号推导。想弄清安全码的位置与规则,可以看CVV 是什么。

读一个号码的实用顺序

如果你手上有一段来路不明的数字,想判断它是不是卡号,可以按这个顺序看:

  • 先数长度。落在 13 到 19 位之间才值得继续,超出范围的可以直接排除。
  • 再看首位。4 到 6 之间的数字最常见,落在其他区间就需要额外理由。
  • 再看前几位。用公开的号段区间比对,判断像哪家卡组织。
  • 最后看校验位。算一遍模 10,能过滤掉纯手误。

这四步只能判断「形状」。「这个号码属于谁」这个问题,任何本地方法都回答不了,因为它只存在于发卡行的记录里。

在本站按格式生成号码

需要一批形状正确、覆盖不同卡组织的号码时,用信用卡号生成器最省事。选定卡组织后,生成结果会按该卡组织公开的号段与真实位数产出,长度和前缀都落在合理区间内,结账页通常能正确识别出品牌。

如果你手上已经有一段号码,切到卡号补全模式,把已知部分填进去,用占位符标出待补的位,就能得到完整号码。生成的全部内容都是合成数据:结构上合法,但从未发行给任何人,也不能用于任何真实交易。

给开发者:输入清洗与显示格式

号码格式带来的第一个坑是输入。用户粘贴卡号时,空格、连字符、全角数字、不可见字符都可能混进来。建议在进入校验之前做一次归一化:去掉分隔符,把全角数字转成半角,然后判断剩下的字符是否全是数字。归一化失败就应该给出「请输入数字」这类明确提示,而不是让它一路走到校验位那一步再报错。

第二个坑是分组显示。卡号在界面上通常每四位加一个空格,读者更容易逐段核对。但请注意,分组显示只是显示:发给后端的应当是纯数字,否则你的长度校验会因为空格而全部失败。把「显示用的格式化」和「传输用的归一化」分成两个函数,是成本最低的预防措施。

第三个坑是长度校验的取舍。建议先按首位数字匹配卡组织,再用该卡组织的长度集合判断,匹配不到时退回一个较宽的范围,而不是直接拒绝。过于严格的长度白名单会在新号段出现时立刻失效,而过于宽松的范围又会放过明显错误的输入。折中做法是:范围判断只用来拦明显错误,真正决定接受与否的是后续的完整校验流程,细节见在代码里校验信用卡号。

最后一个建议与格式本身无关,但同源:把「号码的三段结构」这个概念写进代码的命名里。识别前缀的函数叫识别卡组织,计算校验的部分叫校验位,不要都塞进一个叫「检查卡号」的大函数。当格式规则需要调整时,能一眼看出该改哪一处,比读十遍注释都有用。

下一步

想按卡组织准备测试号码,读各卡组织的测试号段;想知道最后一位的具体算法,读Luhn 算法。

要动手造一批格式正确的号码,直接用信用卡号生成器,选好卡组织批量生成即可。记得把它们当成形状正确的字符串来用,而不是当成卡。

继续阅读

信用卡号生成器(测试用)相关文章