首发地址:简书 - 银行卡号的编码规则及校验
欢迎关注我的简书账号:godson_ds
笔者目前使用的jdk版本是1.6.0_29,Eclipse版本是Juno Release,Build id 20120614-1722。如无特殊说明,本文所有的Java代码都是基于此。
修订记录
版本号 | 修订日期 | 修订说明 |
---|---|---|
V0.1 | 2018/09/02 | 初稿 |
V1.0 | 2018/09/09 | 发布 |
参考资料
- 维基百科 https://en.wikipedia.org/wiki/Payment_card_number
- 维基百科 https://en.wikipedia.org/wiki/Luhn_algorithm
- ISO/IEC 7812-1-2017 Identification cards - Identification of issuers - Part 1: Numbering system
- 中华人民共和国金融行业标准 JR/T 0008-2000 银行卡发卡行标识代码及卡号
- GB/T 15694.1-1995 识别卡 发卡者标识 第1部分:编号体系
- 银联标准卡的成长之路(来源:新浪财经,发布时间:2007年03月14日)
历史背景
2000年,中国人民银行为推动联网通用,组织制定了一系列银行卡业务规范和技术标准。其中《银行卡发卡行标识代码及卡号》规定,在国内发行使用的各种人民币卡必须使用“9”字头BIN。该规定为规范和统一银行卡在国内的发行、使用及联网通用奠定了基础。
随着我国银行卡产业的迅速发展以及国际交流的日益增加,持卡人的境外支付需求越来越多。根据国际标准化组织(ISO)的规定,使用“9”字头BIN的银行卡只能在国内使用。这意味着人民币可自由兑换后,我国国内各发卡机构发行的大量“9”字头BIN银行卡届时可能无法在国外使用。“9”字头BIN的银行卡只能在国内使用的局限性与广大持卡人对境外用卡的支付需求之间的矛盾逐步显现。
为了促进民族银行卡产业的健康持续发展,维护各发卡机构的长远利益,克服“9”字头BIN的银行卡境外使用的局限,在中国人民银行的指导和帮助下,2002年,中国银联代国内各发卡机构统一向ISO(国际标准化组织)申请了800个在国内和国外通行的国际标准BIN(622126至622925)。在取得中国人民银行关于启用银联国际标准发卡行BIN号的批复后,2003年7月,中国银联向各成员机构发布了《关于启用银联国际标准发卡行BIN号的函》,并且为了规范和合理地分配、使用和管理银联国际标准BIN号和已经广为使用的原“9”字头BIN号,中国银联发布了《银联标识卡BIN号分配和管理暂行办法》。从而正式启动了银联国际标准“62”字头BIN号的分配和使用工作,推动各家成员机构开始发行银联标准卡,即具有“银联”标识,卡号前6位采用银联国际标准“62”字头BIN号的银行卡。该卡符合我国统一的业务规范和技术标准,是我国具有自主知识产权的高品质、国际化民族银行卡品牌。
银行卡号的编码规则
银行卡号由最多19位数字组成。
1. 前6位数字被称为发行者识别号码(Issuer Identification Number,缩写为IIN),也称为发卡行识别码(Bank Identification Number,简称BIN),常说的卡BIN就是指它,由中国银联代国内各发卡机构统一向ISO申请。6位IIN的第一位,是主要行业标识符(Major industry identifier,缩写为MII),分配如下:
- 0 - ISO/TC 68和其他行业分配
- 1 - 航空业
- 2 - 航空业,金融业和其他未来行业分配
- 3- 旅游业和娱乐业
- 4 - 银行业和金融业
- 5 - 银行业和金融业
- 6 - 商业和银行业/金融业
- 7 - 石油业和其他未来行业分配
- 8 - 医疗业,电信业和其他未来行业分配
- 9 - 由各国标准团体分配
2. 中间的7~18位由发卡行自定义,表示不同的个人账户号码,最大12位;
3. 最后1位是校验码,使用Luhn算法计算。
需要注意:2017年发布的ISO/IEC 7812-1中,删除了对MII的定义描述,并将IIN码由6位扩展到了8位,但是由于总位数仍然最多19位,所以中间的个人账户号码对应的最大位数由12位减少至10位。所以卡BIN不再只是6位,也需要考虑兼容8位。
Luhn算法
Luhn算法,也称为“模10”算法,是一种简单的校验和(Checksum)算法,一般用于验证身份识别号码,例如信用卡号码、国际移动设备识别码(International Mobile Equipment Identity,缩写为IMEI),美国供应商识别号码,加拿大社会保险号码,以色列身份证号码,希腊社会安全号码等。
Luhn算法在ISO/IEC 7812-1中定义,它不是一种安全的加密哈希函数,设计它的目的只是防止意外出错而不是恶意攻击,即我们常说的防君子不防小人。
使用Luhn算法校验的步骤:
1. 从右边第1个数字(校验数字)开始偶数位乘以2;
2. 把步骤1种获得的乘积的各位数字与原号码中未乘2的各位数字相加;
3. 如果步骤2得到的总和模10为0,则校验通过。
举例说明:
笔者一张过期的信用卡号码为6225760008219524,根据上述步骤进行校验。
序号 | 卡号 | 步骤1 | 步骤2 | 步骤3 |
---|---|---|---|---|
16 | 6 | 6 × 2 = 12 | 1 + 2 | = 3 |
15 | 2 | 2 | + 2 | = 5 |
14 | 2 | 2 × 2 = 4 | + 4 | = 9 |
13 | 5 | 5 | + 5 | = 14 |
12 | 7 | 7 × 2 = 14 | + 1 + 4 | = 19 |
11 | 6 | 6 | + 6 | = 25 |
10 | 0 | 0 × 2 = 0 | + 0 | = 25 |
9 | 0 | 0 | + 0 | = 25 |
8 | 0 | 0 × 2 = 0 | + 0 | = 25 |
7 | 8 | 8 | + 8 | = 33 |
6 | 2 | 2 × 2 = 4 | + 4 | = 37 |
5 | 1 | 1 | + 1 | = 38 |
4 | 9 | 9 × 2 = 18 | + 1 + 8 | = 47 |
3 | 5 | 5 | + 5 | = 52 |
2 | 2 | 2× 2 = 4 | + 4 | = 56 |
1 | 4 | 4 | + 4 | = 60 |
60 % 10 = 0,校验通过。大家可以据此尝试校验自己的银行卡号。
了解Lunh算法校验银行卡号的方法后,很容易推导出使用Luhn算法计算数字字符串的校验数字的方法,仍然以上述银行卡号为例,去掉校验数字后,剩余622576000821952,假设校验数字为 x