本帖最后由 hypnos 于 2020-8-14 01:12 编辑 只针对Amex银行自己发行的Amex卡,别的银行这些卡一般主副卡卡号都一样,所以其实也不需要区分主副卡。
Amex卡号规则Amex卡号总共15位,比Visa,MasterCard,Discover Card少一位。Amex卡号37开头,后面的13位分6组,有不同的用途和意义。这里,我们用ABCDEF代表这6组。一个Amex卡号就可以写成这样:
37AA-BBCCCC-CDEEF
A: 2位,代表国家或者货币,在欧洲这一规律比较整齐,比如43代表英国,49代表法国,50代表德国,当然也有例外,比如同一国家不同货币卡这两位也可能不同;但是在美国,这两位有很多不同数字,也许因为在美国Amex发卡量比较大,所以需要更多的数组吧。
B: 2位,代表卡的类型。比如白金卡一般就是90-99,之类的。当然现在Amex也不太遵守这个规律了。
C: 5位,是这张卡对应的真正信用卡账号。
D: 1位,卡编号,新发行的卡这位都是1,如果卡挂失或者别的一些原因需要换号,就加1(下一个是2),以此类推。
E: 2位,00代表主卡,01-99是副卡。
- 如果卡的最后3位是00X,就是主卡,如果最后3位的前两个数字不是00,就是副卡;
F: 1位,使用 LUHN-10 算法验证这个信用卡号是否有效。
这位数字实际上是体现一点点计算算法的。LUHN-10算法实际上在维基百科上有说明。
这个LUHN-10 算法的具体步骤是这样的:
- 把信用卡号除了最后一位的列出来,比如 (X是最后一位数字)3798 788715 7100X
- 奇数位数字不变,偶数位数字乘以2。
- 如果乘以2以后的数字大于等于10,两位相加。
- 所有奇数位(原样不变)和偶数位(上面步骤2)和3)处理过的)相加。
- 看这个总和的最后一位(个位),如果是0,那么卡号的最后一位就是0,如果不是0,卡号的最后一位就是10减去这个个位数。
下面列出了这个算法给出的上面这个信用卡号的最后一位数,应该而且只能是8。
1)原卡号 3 7 9 8 7 8 8 7 1 5 7 1 0 0 X
2)乘以2 14 16 16 14 10 2 0
3)两位相加 5 7 7 5 1 2 0
4)总和 3 5 9 7 7 7 8 5 1 1 7 2 0 0 62
5)最后一位 X=8
为了方便大家,笔者用统计语言R(这个是开源免费软件,而且安装快捷方便)写了一段小代码。大家可以把自己的Amex卡号输入,最后一位是可以用这段小代码算出来的。笔者试了不少,都对。当然,笔者写程序水平一般,这个程序可能不够优化,不过作为娱乐应该够了。
这也看出,只要前面14位固定,Amex卡号的最后一位是唯一确定的,这也解释了为什么E的2位主副卡序列固定,对应的卡号只有一个(所以,只能有99张副卡)。
总结最后,提醒大家一下:上面的规则看出,Amex卡号最后4位完全是废的,如果前面的11位被人知道了(其实前2位37也是废的),最后4位就基本是唯一确定的;如果前面4位和中间6位被人知道,最后5位其实只有10种可能(倒数第五位从0-9,最后4位基本就是唯一确定的)。卡被盗的几率巨大!
知道副卡卡号,计算主卡卡号的办法:比如副卡卡号是 379878871571016:- 主卡前11位和副卡一样,是37987887157
- 主卡第12位从1开始,如果卡主挂失一次,这个数字升高一个
- 主卡第13,14位一定是00
- 主卡最后一位可以用LUHN-10算法算出。
所以,副卡379878871571016对应的主卡卡号就是下面这些可能:- 379878871571008
- 379878871572006
- 379878871573004
- 379878871574002
- 379878871575009
- 等等
其他信息,姓名,过期日,4位验证码姓名和4位验证码 Amex 不在意,在很多网站购物的时候自己随意输入即可,过期日只有有限组合。
附录:计算Amex卡最后一位的R程序
统计软件R下载安装地址:
https://cran.r-project.org/LastDigit = function(x=37987887157100){
y_vec = rep(0,14)
for(i in 1:14)
y_vec
= floor(x/10^(14-i)) - floor(x/10^(15-i))*10 Total = 0 for(i in 1:7){ Total = Total + y_vec[2*i-1] Total_Even = 2 * y_vec[2*i] if(Total_Even >= 9) Total = Total + Total_Even - 9 else Total = Total + Total_Even } Total_LastDigit = Total - floor(Total/10)*10 if(Total_LastDigit <= 10) LastDigit = 10 - Total_LastDigit if(Total_LastDigit == 10) LastDigit = 0 return(LastDigit)}LastDigit(37987887157100)注:在运行过前面的宏函数之后,只需要修改和运行最后一行LastDigit()就可以算出最后一位。注:本文原文在美国信用卡指南,笔者写。