当前位置:网站首页>go实现 银行卡Luhn校验
go实现 银行卡Luhn校验
2022-04-22 19:43:00 【dz45693】
一、银行卡号码的校验规则
银行卡号码的校验采用Luhn算法,校验过程大致如下:
1. 从右到左给卡号字符串编号,最右边第一位是1,最右边第二位是2,最右边第三位是3….
2. 从右向左遍历,对每一位字符t执行第三个步骤,并将每一位的计算结果相加得到一个数s。
3. 对每一位的计算规则:如果这一位是奇数位,则返回t本身,如果是偶数位,则先将t乘以2得到一个数n,如果n是一位数(小于10),直接返回n,否则将n的个位数和十位数相加返回。
4. 如果s能够整除10,则此号码有效,否则号码无效。
因为最终的结果会对10取余来判断是否能够整除10,所以又叫做模10算法。
二、生成符合Luhn规则的银行卡号测试数据
前面既然摸清了银行卡号的校验规则,那么就可以根据此规则生成一些能够通过Luhn校验的测试数据。
思路:
因为最右边的一位是奇数位,奇数位不需要改变值直接放啥就是啥,这个特性很重要,正好可以用来补齐到正好能够整除10。
所以显然能够推测出生成n位符合Luhn规则的算法:
1. 随机生成n-1位字符,称为字符串x。
2. 先假设字符串x有n位(实际上最右边一位缺失是n-1位,最后一位用0补上占位置),将x按照n位长度计算和s,
3. 上一步得到字符串x的校验和s,将s加上一个数字y,使得它正好可以整除10,这个y就是最右边第一位应该放的数字。
4. x+y做字符串拼接运算,得到最终的n位符合Luhn规则的字符串。
整个代码如下:
package main
import (
"fmt"
"math/rand"
"strconv"
"time"
)
func main() {
fmt.Println(checkCarNum("6226095711989751"))
cardNum := genCardNum("622609", 16)
fmt.Println(cardNum)
fmt.Println(checkCarNum(cardNum))
}
func checkCarNum(cardNum string) bool {
sum, err := getCardNumSum(cardNum)
if err != nil {
return false
}
return sum%10 == 0
}
func getCardNumSum(cardNum string) (int64, error) {
sum := int64(0)
length := len(cardNum)
index := length - 1
for {
t, err := strconv.ParseInt(string(cardNum[index]), 10, 64)
if err != nil {
return 0, err
}
if index%2 == 0 {
t = t * 2
if t >= 10 {
t = t%10 + t/10
}
}
sum += t
if index <= 0 {
break
}
index--
}
return sum, nil
}
func genCardNum(startWith string, totalNum int) string {
result := startWith
length := len(result)
rand.New(rand.NewSource(time.Now().UnixNano()))
for {
result += fmt.Sprintf("%d", rand.Intn(10))
if length == totalNum-1 {
break
}
length++
}
sum, _ := getCardNumSum(result + "0")
t := 10 - sum%10
if t == 10 {
t = 0
}
result += fmt.Sprintf("%d", t)
return result
}
版权声明
本文为[dz45693]所创,转载请带上原文链接,感谢
https://blog.csdn.net/dz45693/article/details/124294450
边栏推荐
- 5篇关于强化学习在金融领域中应用的论文推荐
- 2018-8-10-win10-uwp-商业游戏-1.2.1
- Speak through object prototype. toString. call()
- Deux mécanismes de désactivation de la vérification des messages courts et leurs différences
- Supplement to "continue raspberry pie 4B + OLED: automatic display of IP address after startup", for raspberry PI OS Lite 64 bit
- . net learning notes (III) -- ubiquitous features
- Static dispatch and dynamic dispatch
- mysql alter 最佳实践总结
- 这就是深度学习如此强大的原因
- 深开鸿与亿晟科技签署合作协议,携手构建商显行业新生态
猜你喜欢

quarkus依赖注入之九:bean读写锁

10.4.4 51单片机控制系统8个LED“跑马灯”实验
![[AI vision · quick review of robot papers today, issue 33] Thu, 21 APR 2022](/img/d9/075af1453cb0aded4945074d0643c2.png)
[AI vision · quick review of robot papers today, issue 33] Thu, 21 APR 2022

数据中心碳中和之路,新华三如何全栈赋能?

ASP.NET之WEBAPI和webservice返回json数据

.NET学习笔记(三)----无处不在的特性

短链接设计和思考

MySQL gets the collection of each day according to the start and end date

Huawei equipment configuration policy routing to the side hanging firewall

STM32学习记录006——新建工程模板(基于固件库)
随机推荐
dotnet 通过 WMI 获取设备厂商
Speak through object prototype. toString. call()
When MySQL designs a table, two timestamp fields are required
Golang本地缓存选型对比及原理总结
sqlserver中一个表中树形结构递归数据查询
quarkus依赖注入之九:bean读写锁
2021-06-10 axure本地发布
08-UDFs
(3) MySQL constraints
倒计时案例
让模型训练速度提升2到4倍,「彩票假设」作者的这个全新PyTorch库火了
String.join()和StringUtils.join()优雅解决数组或者集合拼接
【八股文】JUC的使用场景及特点
Sqlserver determines whether a column in the table contains Chinese, English and pure numbers
【自动化测试基础知识】自动化测试的基本概念及常用框架
NAVICAT 中,如何执行存储过程?
关于log4j2的重新加载,以及不同级别日志输出到不同日志文件
FPGA SEU问题与SEM Core
多开关、多业务线设计思考和总结
【2022应届生看过来】一个无经验的大学毕业生,可以转行做软件测试吗?