go語(yǔ)言實(shí)現(xiàn)銀行卡號(hào)Luhn校驗(yàn)
一、銀行卡號(hào)碼的校驗(yàn)規(guī)則
銀行卡號(hào)碼的校驗(yàn)采用Luhn算法,校驗(yàn)過程大致如下:
1. 從右到左給卡號(hào)字符串編號(hào),最右邊第一位是1,最右邊第二位是2,最右邊第三位是3….
2. 從右向左遍歷,對(duì)每一位字符t執(zhí)行第三個(gè)步驟,并將每一位的計(jì)算結(jié)果相加得到一個(gè)數(shù)s。
3. 對(duì)每一位的計(jì)算規(guī)則:如果這一位是奇數(shù)位,則返回t本身,如果是偶數(shù)位,則先將t乘以2得到一個(gè)數(shù)n,如果n是一位數(shù)(小于10),直接返回n,否則將n的個(gè)位數(shù)和十位數(shù)相加返回。
4. 如果s能夠整除10,則此號(hào)碼有效,否則號(hào)碼無(wú)效。
因?yàn)樽罱K的結(jié)果會(huì)對(duì)10取余來(lái)判斷是否能夠整除10,所以又叫做模10算法。
二、生成符合Luhn規(guī)則的銀行卡號(hào)測(cè)試數(shù)據(jù)
前面既然摸清了銀行卡號(hào)的校驗(yàn)規(guī)則,那么就可以根據(jù)此規(guī)則生成一些能夠通過Luhn校驗(yàn)的測(cè)試數(shù)據(jù)。
思路:
因?yàn)樽钣疫叺囊晃皇瞧鏀?shù)位,奇數(shù)位不需要改變值直接放啥就是啥,這個(gè)特性很重要,正好可以用來(lái)補(bǔ)齊到正好能夠整除10。
所以顯然能夠推測(cè)出生成n位符合Luhn規(guī)則的算法:
1. 隨機(jī)生成n-1位字符,稱為字符串x。
2. 先假設(shè)字符串x有n位(實(shí)際上最右邊一位缺失是n-1位,最后一位用0補(bǔ)上占位置),將x按照n位長(zhǎng)度計(jì)算和s,
3. 上一步得到字符串x的校驗(yàn)和s,將s加上一個(gè)數(shù)字y,使得它正好可以整除10,這個(gè)y就是最右邊第一位應(yīng)該放的數(shù)字。
4. x+y做字符串拼接運(yùn)算,得到最終的n位符合Luhn規(guī)則的字符串。
整個(gè)代碼如下:
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 }
參考:銀行卡號(hào)碼校驗(yàn)算法(Luhn算法,又叫模10算法)
以上就是go語(yǔ)言實(shí)現(xiàn)銀行卡Luhn校驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于go銀行卡Luhn校驗(yàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go可變參數(shù)函數(shù)的實(shí)現(xiàn)
可變參數(shù)函數(shù)是指函數(shù)參數(shù)的某個(gè)參數(shù)可有可無(wú),即這個(gè)參數(shù)的個(gè)數(shù)可以為0會(huì)多個(gè),可變參數(shù)函數(shù)參數(shù)在日常編程中大量使用,本文主要介紹了Go可變參數(shù)函數(shù)的實(shí)現(xiàn),感興趣的可以了解一下2023-12-12Hugo?Config模塊構(gòu)建實(shí)現(xiàn)源碼剖析
這篇文章主要為大家介紹了Hugo?Config模塊構(gòu)建實(shí)現(xiàn)源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02GoLang jwt無(wú)感刷新與SSO單點(diǎn)登錄限制解除方法詳解
這篇文章主要介紹了GoLang jwt無(wú)感刷新與SSO單點(diǎn)登錄限制解除方法,JWT是一個(gè)簽名的JSON對(duì)象,通常用作Oauth2的Bearer token,JWT包括三個(gè)用.分割的部分。本文將利用JWT進(jìn)行認(rèn)證和加密,感興趣的可以了解一下2023-03-03golang 實(shí)現(xiàn)tcp server端和client端,并計(jì)算RTT時(shí)間操作
這篇文章主要介紹了golang 實(shí)現(xiàn)tcp server端和client端,并計(jì)算RTT時(shí)間操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-12-12源碼剖析Golang中map擴(kuò)容底層的實(shí)現(xiàn)
之前的文章詳細(xì)介紹過Go切片和map的基本使用,以及切片的擴(kuò)容機(jī)制。本文針對(duì)map的擴(kuò)容,會(huì)從源碼的角度全面的剖析一下map擴(kuò)容的底層實(shí)現(xiàn),需要的可以參考一下2023-03-03Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)之strconv的使用
本文主要介紹了Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)之strconv的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03