.NET Core 如何验证信用卡卡号

_

点击上方蓝字关注“汪宇杰博客”

导语

最近在家闲的蛋疼需要写点文章。正好我本人在金融科技公司工作,对信用卡业务略有了解。我们看看如何在 .NET Core 里验证一个信用卡的卡号是否合法。

信用卡卡号组成

首先,信用卡的卡号一般为16位,也有少许14或15位的情况。其中,前6-8位用来标识卡片类型和发卡机构,称之为 BIN 码(Bank Identification Number)。有个网站可以查询:https://binlists.com/。万事达(Master Card)以 51-55 开头,例如交行的万事达白金卡 BIN 码为 522964。Visa 卡以 4 开头,例如我司(Green Dot)的 437303。剩余位数由各家发卡机构自己发挥,其中会包含持卡人信息、校验码等,由于不同银行规则不一样,不多介绍。但是,任何卡号都必须满足一个行业内著名的规律:MOD10算法。

Luhn / MOD 10 算法

根据维基百科的描述,Luhn 算法,也叫模10算法,由科学家 Hans Peter Luhn 在1960年发明,广泛用于校验借记卡、信用卡卡号是否正确,其标准为 ISO/IEC 7812-1。它的目的不是用于加密卡号,而是为了防止人为出错。

计算方法如下,比如对于卡号 :

6011000990139424

末尾的数字 4 叫做校验码,剩下的数字为 601100099013942。将他们从右到左排开,得到:

2 4 9 3 1 09 9 0 0 0 1 1 0 6

从第一位 2 开始,相隔一个数字的值 x2,即上面红色标出的奇数位翻倍,得到:

4 4 18 3 2 018 9 0 0 0 1 2 0 12

发现这里面有超过10的两位数,即蓝色标出的18、18、12,对于大于10的数,将其 -9,得到:

4 4 9 3 2 09 9 0 0 0 1 2 0 3

把所有的数加起来,得到:46

将这个结果乘以9,46 x 9 = 414

发现 414个位上的数字 4 和我们在第一步中拿掉的 4 相等,这个就是校验码的作用,相等就对了!最后把校验码也加上,46 + 4 = 50,而 50 % 10 = 0,得出结论 6011000990139424 是一个合法的信用卡卡号。

将这个算法用 C# 代码表示,即:

public static bool IsLuhnValid(int[] digits)

{

    var sum = 0;

    var alt = false;

    for (var i = digits.Length - 1; i >= 0; i--)

    {

        if (alt)

        {

            digits[i] *= 2;

            if (digits[i] > 9)

            {

                digits[i] -= 9;

            }

        }

        sum += digits[i];

        alt = !alt;

    }

    return sum % 10 == 0;

}

对于输入的字符串类型的卡号,也可以用个LINQ技巧一行代码转成 int 数组:

public static int[] GetDigitsArrayFromCardNumber(string cardNumber)

{

    var digits = cardNumber.Select(p => int.Parse(p.ToString())).ToArray();

    return digits;

}

写了个轮子

基于以上的知识,我今天抽空写了个开源库,可用于校验信用卡卡号是否合法,目前还有一些遗漏的场景(比如14、15位信用卡的校验),大家可以参考。

dotnet add package Edi.CreditCardUtils --version 0.1.0-alpha

https://github.com/EdiWang/Edi.CreditCardUtils

这个库的验证步骤为:

  1. 输入的字符串是否为16位数字

  2. 这串数字是否满足 Luhn 算法

  3. 该卡是否为已知的某发行商的BIN (可选参数,也可自己拓展)

验证返回类型为:

public class CreditCardValidationResult

{

    public CreditCardNumberFormat CreditCardNumberFormat { get; set; }

    public string CardType { get; set; }

}

public enum CreditCardNumberFormat

{

    None = 0,

    Valid_LuhnOnly = 100, // 验证通过,仅满足 Luhn

    Valid_BrandTest = 101, // 验证通过,满足 Luhn 并且为已知 BIN

    Invalid_BadStringFormat = 200, // 验证失败,非信用卡卡号格式

    Invalid_LuhnFailure = 201 // 验证失败,不满足 Luhn

}

使用方法可以参考单元测试中的案例,如验证一个卡号 4012888888881881,传入两个已知BIN(Visa、MasterCard)的验证器,会返回是否验证通过以及识别出的卡类型:

var result = CreditCardValidator.ValidCardNumber("4012888888881881", new List<ICreditCardBrandFormatValidator>

{

    new VisaFormatValidator(),

    new MasterCardFormatValidator()

});

Assert.IsTrue(result.CreditCardNumberFormat == CreditCardNumberFormat.Valid_BrandTest && result.CardType == "Visa");

对于自定义的BIN,比如你想写建行的BIN验证器,可以实现 ICreditCardBrandFormatValidator 接口,给个名字和正则就行,就像 Visa 的这个:

public class VisaFormatValidator : ICreditCardBrandFormatValidator

{

    public string BrandName => "Visa";

    public string BrandRegEx => "^4[0-9]{12}(?:[0-9]{3})?$";

}

参考:https://en.wikipedia.org/wiki/Luhn_algorithm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311849.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构---关键路径

数据结构—关键路径 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #include "stack.h" #define typeNode int //每个头结点的标识数据类型 #define N 100 //最大结点数 int degree[N];//结点入度数,通过…

SkyWalking学习笔记(Window环境 本地环境)

基于 Windows 环境使用 SkyAPM-dotnet 来介绍一下 SkyWalking&#xff0c; SkyAPM-dotnet 是 SkyWalking 的 .NET Agent环境要求JDK8Elasticsearch8080,9200,10800,11800,12800 端口不被占用Elasticsearch安装Elasticsearch下载安装 参考官方教程.Elasticsearch下载安装官方教程…

word List16

word List16 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

python二分法求方程的根_Python查找函数f(x)=0根的解决方法

线性代数分享方程f(x)0的根 函数F(x)0的重根与F(x)0的根有什么关系&#xff1f;有些人一旦错过了&#xff0c;就是一辈子不再主动联系&#xff0c;不愿打扰你的生活&#xff0c;连偶尔的寒暄都没有&#xff0c;成长就是这样的&#xff0c;不断的告别&#xff0c;不断的遇见。 请…

word List 17

word List 17 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

pb 如何导出csv_如何计算指数温度?

指数温度的高低与价格高低没有必然的联系&#xff0c;指数温度的高低反映的是在历史中低于指数当前估值出现的概率。温度越低说明在历史上低于当前估值的概率越小&#xff0c;指数的价值越被低估&#xff0c;上涨的概率越大&#xff1b;温度越高说明在历史上低于当前估值的概率…

算法问题---两艘船是否有最大承载量

算法问题—两艘船是否有最大承载量 代码&#xff1a; 栈代码&#xff1a; #pragma once #include<stdio.h> #define maxSize 100 typedef struct stack {int * base;int * top; }stack; bool init(stack & Stack) {//栈的初始化Stack.base new int[maxSize];if (…

python标准库time_Python 标准库之时间篇

写在之前 大家好&#xff0c;这是首发在我公众号「Python空间」的第 69 篇文章&#xff0c;欢迎关注&#xff0c;期待和你的交流。 在昨天的文章&#xff08;Python 标准库之日期&#xff09;中我们学习了 Python 标准库中「日期 & 时间」中的「日期」&#xff0c;本来想昨…

《ASP.NET Core 微服务实战》-- 读书笔记(第12章)

第 12 章 设计汇总微服务开发并不是要学习 C#、Java 或者 Go 编程--而是要学习如何开发应用以适应并充分利用弹性伸缩环境的优势&#xff0c;它们对托管环境没有偏好&#xff0c;并能瞬间启停换句话说&#xff0c;我们要学习如何开发云原生应用识别并解决反模式我们既然已经学习…

[蓝桥杯2017初赛]纸牌三角形-枚举permutation+数论

题目描述 A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形&#xff08;A按1计算&#xff09;。要求每个边的和相等。 下图就是一种排法这样的排法可能会有很多。 如果考虑旋转、镜像后相同的算同一种&#xff0c;一共有多少种不同的排法呢&#xff1f; 输出 输出一个整数表示答…

算法----最大承载量下的最大价值问题

算法----最大承载量下的最大价值问题 代码&#xff1a; 栈代码&#xff1a;&#xff08;存储哪些是需要的价值物&#xff09; #pragma once #include<stdio.h> #define maxSize 100 typedef struct stack {int * base;int * top; }stack; bool init(stack & Stack…

oracle多条件分组统计_多条件统计,就必须用Ifs系列函数,绝对的高能!

数据统计&#xff0c;我们并不陌生&#xff0c;但是在实际的工作或应用中&#xff0c;数据统计都是附加条件的&#xff0c;而且大多情况下是“多条件”的&#xff0c;此时&#xff0c;我们必须掌握“Ifs”系列函数。一、多条件判断&#xff1a;Ifs函数。功能&#xff1a;判断指…

AcWing 895. 最长上升子序列

给定一个长度为N的数列&#xff0c;求数值严格单调递增的子序列的长度最长是多少。 输入格式 第一行包含整数N。 第二行包含N个整数&#xff0c;表示完整序列。 输出格式 输出一个整数&#xff0c;表示最大长度。 数据范围 1≤N≤1000&#xff0c; −10^9≤数列中的数≤ 10…

word List18

word List18 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

AcWing 1015. 摘花生

Hello Kitty想摘点花生送给她喜欢的米老鼠。 她来到一片有网格状道路的矩形花生地(如下图)&#xff0c;从西北角进去&#xff0c;东南角出来。 地里每个道路的交叉点上都有种着一株花生苗&#xff0c;上面有若干颗花生&#xff0c;经过一株花生苗就能摘走该它上面所有的花生。…

干货,不小心执行了rm -f,除了跑路,如何恢复?

作者&#xff1a;justmine头条号&#xff1a;大数据与云原生微信公众号&#xff1a;大数据与云原生创作不易&#xff0c;在满足创作共用版权协议的基础上可以转载&#xff0c;但请以超链接形式注明出处。为了方便阅读&#xff0c;微信公众号已按分类排版&#xff0c;后续的文章…

数据结构----二叉树叶子结点到根节点的高度计算

数据结构----二叉树叶子结点到根节点的高度计算 代码&#xff1a; #include<stdio.h> #include<stdlib.h> typedef struct bstTree {int data;struct bstTree* lchild, *rchild; }bstTree; void createBSTTree(bstTree* & T, int data) {//创建二叉排序树bst…

nginx 带宽_前端工程师不可不知的Nginx知识

历史背景互联网的全球化导致了互联网的数据量快速增长&#xff0c;加上在本世纪初摩尔定律在单核 CPU 上的失效&#xff0c;CPU 朝着多核方向发展&#xff0c;而 Apache 显然并没有做好多核架构的准备&#xff0c;它的一个进程同一时间只能处理一个连接&#xff0c;处理完一个请…

网格路径最小数字和

给定一个包含非负整数的 m x n 网格&#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 数据范围&#xff1a; n < 100,m < 100; 输入&#xff1a; 3 3 1 3 1 1 5 1 4 2 1 输出&a…

word List 19

word List 19 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;