feat: bank card.
This commit is contained in:
13
bank_card/README.md
Normal file
13
bank_card/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# 银行卡BIN查询银行
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [China UnionPay Bank Card BIN Checker](https://github.com/hexindai/bcbc)
|
||||
- [CommonUtilLibrary](https://github.com/AbrahamCaiJin/CommonUtilLibrary/blob/master/CommonUtil/src/main/java/com/jingewenku/abrahamcaijin/commonutil/BankCheck.java)
|
||||
- [Luhn algorithm - wikipedia](https://en.wikipedia.org/wiki/Luhn_algorithm)
|
||||
- [Luhn algorithm - geeksforgeeks](https://www.geeksforgeeks.org/luhn-algorithm/)
|
||||
- [Luhn’s algorithm to validate credit / debit card Numbers](https://medium.com/@akshaymohite/luhns-algorithm-to-validate-credit-debit-card-numbers-1952e6c7a9d0)
|
||||
- [干货丨银行卡号编码规则及其应用](https://www.woshipm.com/pd/371041.html)
|
||||
- [giraffe-lib](https://github.com/giraffe-lib/bankInfo/blob/main/src/map.js)
|
||||
- [BankCards](https://github.com/geekgao/BankCards/blob/master/bankcode.py)
|
||||
- [bcbc](https://github.com/hexindai/bcbc)
|
||||
BIN
bank_card/bank_card.db
Normal file
BIN
bank_card/bank_card.db
Normal file
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
package common
|
||||
package bank_card
|
||||
|
||||
import "strings"
|
||||
|
||||
@@ -629,58 +629,6 @@ var BANKNAME = []string{
|
||||
"玉溪市商业银行·红塔卡",
|
||||
}
|
||||
|
||||
// IsValidLuhn 使用Luhn算法校验银行卡号码
|
||||
// @see https://en.wikipedia.org/wiki/Luhn_algorithm
|
||||
// @see https://www.geeksforgeeks.org/luhn-algorithm/
|
||||
// @see https://medium.com/@akshaymohite/luhns-algorithm-to-validate-credit-debit-card-numbers-1952e6c7a9d0
|
||||
// @see https://www.woshipm.com/pd/371041.html
|
||||
func IsValidLuhn(cardNo string) bool {
|
||||
length := len(cardNo)
|
||||
if length == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if !isNumberString(cardNo) {
|
||||
return false
|
||||
}
|
||||
|
||||
sum := 0
|
||||
second := false
|
||||
for i := length - 1; i >= 0; i-- {
|
||||
d := cardNo[i] - '0'
|
||||
|
||||
if second == true {
|
||||
d = d * 2
|
||||
}
|
||||
|
||||
sum += int(d) / 10
|
||||
sum += int(d) % 10
|
||||
|
||||
second = !second
|
||||
}
|
||||
|
||||
return sum%10 == 0
|
||||
}
|
||||
|
||||
func isNumberString(s string) bool {
|
||||
length := len(s)
|
||||
for i := 0; i < length; i++ {
|
||||
if s[i] < '0' || s[i] > '9' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsValidBankCardNo 是否合法的银行卡号
|
||||
func IsValidBankCardNo(cardNo string) bool {
|
||||
length := len(cardNo)
|
||||
if length < 12 || length > 19 {
|
||||
return false
|
||||
}
|
||||
return IsValidLuhn(cardNo)
|
||||
}
|
||||
|
||||
// GetNameOfBank 通过银行卡 的前六位确定 判断银行开户行及卡种
|
||||
// @see https://github.com/AbrahamCaiJin/CommonUtilLibrary/blob/master/CommonUtil/src/main/java/com/jingewenku/abrahamcaijin/commonutil/BankCheck.java
|
||||
func GetNameOfBank(cardNo string) string {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package common
|
||||
package bank_card
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -7,106 +7,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsValidLuhn(t *testing.T) {
|
||||
var validBankCards = []string{
|
||||
"79927398713",
|
||||
"6226095711989751",
|
||||
"49927398716",
|
||||
"1234567812345670",
|
||||
"356938035643809",
|
||||
"1111222233334444",
|
||||
"374652346956782346957823694857692364857368475368",
|
||||
"6228480402564890018",
|
||||
"6228480402637874213",
|
||||
"6228481552887309119",
|
||||
"6228480801416266113",
|
||||
"6228481698729890079",
|
||||
"6222081106004039591",
|
||||
}
|
||||
|
||||
var invalidBankCards = []string{
|
||||
"49927398717",
|
||||
"1234567812345678",
|
||||
"314143525252",
|
||||
"534618613411236",
|
||||
"1234567879855431",
|
||||
"374652346956782346957823694857692364857387456834",
|
||||
"79927398710",
|
||||
"79927398711",
|
||||
"79927398711",
|
||||
"79927398712",
|
||||
"79927398714",
|
||||
"79927398715",
|
||||
"79927398716",
|
||||
"79927398717",
|
||||
"79927398718",
|
||||
"79927398719",
|
||||
"621661280000447287",
|
||||
}
|
||||
|
||||
for _, w := range validBankCards {
|
||||
t.Run("valid bank card: "+w, func(t *testing.T) {
|
||||
assert.True(t, IsValidLuhn(w))
|
||||
})
|
||||
}
|
||||
|
||||
for _, w := range invalidBankCards {
|
||||
t.Run("invalid bank card: "+w, func(t *testing.T) {
|
||||
assert.False(t, IsValidLuhn(w))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidBankCardNo(t *testing.T) {
|
||||
var validBankCards = []string{
|
||||
"6226095711989751",
|
||||
"6228480402564890018",
|
||||
"6228480402637874213",
|
||||
"6228481552887309119",
|
||||
"6228480801416266113",
|
||||
"6228481698729890079",
|
||||
"6222081106004039591",
|
||||
"1234567812345670",
|
||||
"356938035643809",
|
||||
"1111222233334444",
|
||||
}
|
||||
|
||||
var invalidBankCards = []string{
|
||||
"49927398717",
|
||||
"1234567812345678",
|
||||
"314143525252",
|
||||
"534618613411236",
|
||||
"1234567879855431",
|
||||
"374652346956782346957823694857692364857387456834",
|
||||
"79927398710",
|
||||
"79927398711",
|
||||
"79927398711",
|
||||
"79927398712",
|
||||
"79927398714",
|
||||
"79927398715",
|
||||
"79927398716",
|
||||
"79927398717",
|
||||
"79927398718",
|
||||
"79927398719",
|
||||
"621661280000447287",
|
||||
"79927398713",
|
||||
"49927398716",
|
||||
"374652346956782346957823694857692364857368475368",
|
||||
}
|
||||
|
||||
for _, w := range validBankCards {
|
||||
t.Run("valid bank card: "+w, func(t *testing.T) {
|
||||
assert.True(t, IsValidBankCardNo(w))
|
||||
})
|
||||
}
|
||||
|
||||
for _, w := range invalidBankCards {
|
||||
t.Run("invalid bank card: "+w, func(t *testing.T) {
|
||||
assert.False(t, IsValidBankCardNo(w))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNameOfBank(t *testing.T) {
|
||||
var validBankCards = []string{
|
||||
"6226095711989751",
|
||||
|
||||
1710
bank_card/bin.csv
Normal file
1710
bank_card/bin.csv
Normal file
File diff suppressed because it is too large
Load Diff
161
bank_card/database.go
Normal file
161
bank_card/database.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package bank_card
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/mattn/go-sqlite3"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
//go:embed bank_card.db
|
||||
var embeddedDatabase []byte
|
||||
|
||||
type Database struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewDatabase() *Database {
|
||||
return &Database{}
|
||||
}
|
||||
|
||||
// OpenFromFile 从文件打开数据库
|
||||
func (d *Database) OpenFromFile() {
|
||||
db, err := sql.Open("sqlite3", "bank_card.db")
|
||||
if err != nil {
|
||||
panic("failed to connect database")
|
||||
}
|
||||
|
||||
d.db = db
|
||||
|
||||
d.initTables()
|
||||
}
|
||||
|
||||
// OpenFromEmbed 从内嵌文件打开数据库
|
||||
func (d *Database) OpenFromEmbed() error {
|
||||
db, err := sql.Open("sqlite3", "file::memory:?mode=ro&cache=shared")
|
||||
if err != nil {
|
||||
panic("failed to connect database")
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := db.Conn(context.Background())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
if err = conn.Raw(func(raw interface{}) error {
|
||||
return raw.(*sqlite3.SQLiteConn).Deserialize(embeddedDatabase, "")
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
conn.Close()
|
||||
|
||||
d.db = db
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Database) Close() {
|
||||
if d.db != nil {
|
||||
_ = d.db.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// initTables 创建表
|
||||
func (d *Database) initTables() {
|
||||
strSql := `
|
||||
CREATE TABLE IF NOT EXISTS bank_cards
|
||||
(
|
||||
bin INTEGER PRIMARY KEY,
|
||||
bank_code TEXT,
|
||||
card_name TEXT,
|
||||
card_type TEXT,
|
||||
card_length INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS banks
|
||||
(
|
||||
id INTEGER PRIMARY KEY autoincrement,
|
||||
bank_code TEXT,
|
||||
bank_name TEXT
|
||||
);
|
||||
`
|
||||
_, err := d.db.Exec(strSql)
|
||||
if err != nil {
|
||||
log.Println("initial database table failed:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Database) insertDataToBankTable(data *Bank) {
|
||||
strSql := fmt.Sprintf("INSERT INTO banks (bank_code, bank_name) VALUES ('%s', '%s');", data.BankCode, data.BankName)
|
||||
_, err := d.db.Exec(strSql)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Database) insertDataToBankCardTable(data *BankCard) {
|
||||
strSql := fmt.Sprintf("INSERT INTO bank_cards (bin, bank_code, card_name, card_type, card_length) VALUES (%d, '%s', '%s', '%s', %d);",
|
||||
data.BIN, data.BankCode, data.CardName, data.CardType, data.CardLength)
|
||||
_, err := d.db.Exec(strSql)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
// queryBank 查询银行信息
|
||||
func (d *Database) queryBank(bankCode string) *Bank {
|
||||
strSql := fmt.Sprintf("SELECT * FROM banks WHERE bank_code = '%s' LIMIT 1;", bankCode)
|
||||
rows, err := d.db.Query(strSql)
|
||||
if err != nil {
|
||||
log.Fatal("query bank failed:", err)
|
||||
return nil
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
rows.Next()
|
||||
var bank Bank
|
||||
if err = rows.Scan(&bank.Id, &bank.BankCode, &bank.BankName); err != nil {
|
||||
log.Fatal("scan bank failed:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
//fmt.Printf("bank = %v\n", bank)
|
||||
|
||||
return &bank
|
||||
}
|
||||
|
||||
// queryBankCard 查询银行卡信息
|
||||
func (d *Database) queryBankCard(bin uint32) *BankCard {
|
||||
strSql := fmt.Sprintf("SELECT * FROM bank_cards WHERE bin = '%d' LIMIT 1;", bin)
|
||||
rows, err := d.db.Query(strSql)
|
||||
if err != nil {
|
||||
log.Fatal("query bank card failed:", err)
|
||||
return nil
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
rows.Next()
|
||||
var bankCard BankCard
|
||||
if err = rows.Scan(&bankCard.BIN, &bankCard.BankCode, &bankCard.CardName, &bankCard.CardType, &bankCard.CardLength); err != nil {
|
||||
log.Fatal("scan bank card failed:", err)
|
||||
return nil
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
bank := d.queryBank(bankCard.BankCode)
|
||||
if bank != nil {
|
||||
bankCard.BankName = bank.BankName
|
||||
}
|
||||
|
||||
//fmt.Printf("bankCard = %v\n", bankCard)
|
||||
|
||||
return &bankCard
|
||||
}
|
||||
163
bank_card/database_test.go
Normal file
163
bank_card/database_test.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package bank_card
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestImportBankName(t *testing.T) {
|
||||
db := NewDatabase()
|
||||
db.OpenFromFile()
|
||||
defer db.Close()
|
||||
|
||||
file, err := os.Open("name.csv")
|
||||
if err != nil {
|
||||
fmt.Println("Read file err, err =", err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fileinfo, err := file.Stat()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
filesize := fileinfo.Size()
|
||||
buffer := make([]byte, filesize)
|
||||
|
||||
_, err = file.Read(buffer)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
r := csv.NewReader(strings.NewReader(string(buffer)))
|
||||
|
||||
for {
|
||||
record, err := r.Read()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(record) == 2 && len(record[0]) > 0 && len(record[1]) > 0 {
|
||||
db.insertDataToBankTable(&Bank{BankCode: record[0], BankName: record[1]})
|
||||
}
|
||||
|
||||
fmt.Println(record)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportBankCard(t *testing.T) {
|
||||
db := NewDatabase()
|
||||
db.OpenFromFile()
|
||||
defer db.Close()
|
||||
|
||||
file, err := os.Open("bin.csv")
|
||||
if err != nil {
|
||||
fmt.Println("Read file err, err =", err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
filesize := fileInfo.Size()
|
||||
buffer := make([]byte, filesize)
|
||||
|
||||
_, err = file.Read(buffer)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
r := csv.NewReader(strings.NewReader(string(buffer)))
|
||||
|
||||
for {
|
||||
record, err := r.Read()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(record) == 4 && len(record[0]) > 0 && len(record[1]) > 0 && len(record[2]) > 0 && len(record[3]) > 0 {
|
||||
bin, _ := strconv.Atoi(record[0])
|
||||
cardLength, _ := strconv.Atoi(record[3])
|
||||
db.insertDataToBankCardTable(&BankCard{
|
||||
BIN: uint32(bin),
|
||||
BankCode: record[1],
|
||||
CardType: record[2],
|
||||
CardLength: uint32(cardLength),
|
||||
})
|
||||
}
|
||||
|
||||
fmt.Println(record)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportBankCardSingle(t *testing.T) {
|
||||
db := NewDatabase()
|
||||
db.OpenFromFile()
|
||||
defer db.Close()
|
||||
|
||||
binStr := "620114|620187|620046"
|
||||
strs := strings.Split(binStr, "|")
|
||||
var bins []uint32
|
||||
for _, str := range strs {
|
||||
bin, _ := strconv.Atoi(str)
|
||||
bins = append(bins, uint32(bin))
|
||||
}
|
||||
|
||||
bankCode := "ABC"
|
||||
cardType := "DC"
|
||||
cardLength := 13 + len(strs[0])
|
||||
for _, data := range bins {
|
||||
bankData := &BankCard{
|
||||
BIN: data,
|
||||
BankCode: bankCode,
|
||||
CardType: cardType,
|
||||
CardLength: uint32(cardLength),
|
||||
}
|
||||
db.insertDataToBankCardTable(bankData)
|
||||
fmt.Println(bankData)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenFromEmbed(t *testing.T) {
|
||||
db := NewDatabase()
|
||||
defer db.Close()
|
||||
|
||||
err := db.OpenFromEmbed()
|
||||
assert.Nil(t, err)
|
||||
|
||||
var bank *Bank
|
||||
bank = db.queryBank("ABC")
|
||||
assert.NotNil(t, bank)
|
||||
assert.Equal(t, bank.BankCode, "ABC")
|
||||
assert.Equal(t, bank.BankName, "中国农业银行")
|
||||
|
||||
var bankCard *BankCard
|
||||
bankCard = db.queryBankCard(620114)
|
||||
assert.NotNil(t, bankCard)
|
||||
assert.Equal(t, bankCard.BankCode, "ICBC")
|
||||
assert.Equal(t, bankCard.BankName, "中国工商银行")
|
||||
assert.Equal(t, bankCard.CardType, "PC")
|
||||
assert.Equal(t, bankCard.CardName, "")
|
||||
assert.Equal(t, bankCard.CardLength, uint32(19))
|
||||
}
|
||||
14
bank_card/go.mod
Normal file
14
bank_card/go.mod
Normal file
@@ -0,0 +1,14 @@
|
||||
module github.com/tx7do/kratos-utils/bank_card
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/mattn/go-sqlite3 v1.14.17
|
||||
github.com/stretchr/testify v1.8.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
12
bank_card/go.sum
Normal file
12
bank_card/go.sum
Normal file
@@ -0,0 +1,12 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
||||
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
42
bank_card/models.go
Normal file
42
bank_card/models.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package bank_card
|
||||
|
||||
type CardType string
|
||||
|
||||
const (
|
||||
CardTypeDC CardType = "DC" // 储蓄卡
|
||||
CardTypeCC CardType = "CC" // 信用卡
|
||||
CardTypeSCC CardType = "SCC" // 准贷记卡
|
||||
CardTypePC CardType = "PC" // 预付费卡
|
||||
)
|
||||
|
||||
// Bank 银行信息
|
||||
type Bank struct {
|
||||
Id uint32 `gorm:"primarykey,column:id"` // ID
|
||||
BankCode string `gorm:"uniqueIndex,column:bank_code"` // 银行简称
|
||||
BankName string `gorm:"column:bank_name"` // 银行名称
|
||||
}
|
||||
|
||||
// BankCard 银行卡信息
|
||||
type BankCard struct {
|
||||
BIN uint32 `gorm:"primarykey,column:bin"` // 银行识别码
|
||||
BankCode string `gorm:"column:bank_code"` // 银行代码
|
||||
BankName string // 银行名称
|
||||
CardType string `gorm:"column:card_type"` // 银行卡类型
|
||||
CardName string `gorm:"column:card_name"` // 银行卡名称
|
||||
CardLength uint32 `gorm:"column:card_length"` // 银行卡号长度
|
||||
}
|
||||
|
||||
// CardTypeName 将卡类型转为类型名
|
||||
func (b *BankCard) CardTypeName() string {
|
||||
switch CardType(b.CardType) {
|
||||
case CardTypeDC:
|
||||
return "储蓄卡"
|
||||
case CardTypeCC:
|
||||
return "信用卡"
|
||||
case CardTypeSCC:
|
||||
return "准贷记卡"
|
||||
case CardTypePC:
|
||||
return "预付费卡"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
299
bank_card/name.csv
Normal file
299
bank_card/name.csv
Normal file
@@ -0,0 +1,299 @@
|
||||
ABC,中国农业银行
|
||||
AEON,AEON银行
|
||||
ARCU,安徽省农村信用社
|
||||
ASCB,鞍山银行
|
||||
AYCB,安阳银行
|
||||
|
||||
BANKWF,潍坊银行
|
||||
BCDMMA,澳门商业银行
|
||||
BDCBANK,保定银行
|
||||
BEAHK,东亚银行有限公司
|
||||
BGB,广西北部湾银行
|
||||
BHB,河北银行
|
||||
BJBANK,北京银行
|
||||
BJRCB,北京农村商业银行
|
||||
BNU,大西洋银行
|
||||
BOC,中国银行
|
||||
BOCD,承德银行
|
||||
BOCFCB,中银富登村镇银行
|
||||
BOCY,朝阳银行
|
||||
BOCZ,沧州银行
|
||||
BOD,东莞银行
|
||||
BODD,丹东银行
|
||||
BOHAIB,渤海银行
|
||||
BOHN,海南省农村信用社
|
||||
BOJZ,锦州银行
|
||||
BOL,洛阳银行
|
||||
BOP,平顶山银行
|
||||
BOQH,青海银行
|
||||
BOQZ,泉州银行
|
||||
BOSH,新韩银行(中国)
|
||||
BOSZ,苏州银行
|
||||
BOYK,营口银行
|
||||
BOZK,周口银行
|
||||
BSB,包商银行
|
||||
BZMD,驻马店银行
|
||||
|
||||
CAB,宝鸡商行
|
||||
CABANK,长安银行
|
||||
CBBQS,城市商业银行资金清算中心
|
||||
CBKF,开封市商业银行
|
||||
CCB,中国建设银行
|
||||
CCQTGB,重庆三峡银行
|
||||
CDB,国家开发银行
|
||||
CDCB,成都银行
|
||||
CDRCB,成都农商银行
|
||||
CEB,中国光大银行
|
||||
CEP,中银通商务支付有限公司
|
||||
CGNB,南充市商业银行
|
||||
CHB,创兴银行有限公司
|
||||
CIB,兴业银行
|
||||
CITI,花旗银行(中国)
|
||||
CITIC,中信银行
|
||||
CJCCB,苏州长江商业银行
|
||||
CMB,招商银行
|
||||
CMBC,中国民生银行
|
||||
COMM,交通银行
|
||||
COMMHK,交通银行香港分行
|
||||
CQBANK,重庆银行
|
||||
CRCBANK,重庆农村商业银行
|
||||
CSC,CSC借记卡
|
||||
CSCB,长沙银行
|
||||
CSRCB,常熟农商银行
|
||||
CYBC,集友银行
|
||||
CYS,中国银盛
|
||||
CZBANK,浙商银行
|
||||
CZCB,浙江稠州商业银行
|
||||
CZCCB,长治市商业银行
|
||||
CZRCB,常州农村信用联社
|
||||
|
||||
DAQINGB,龙江银行
|
||||
DBS,星展银行
|
||||
DBSCN,星展银行
|
||||
DLB,大连银行
|
||||
DRCBCL,东莞农村商业银行
|
||||
DSB,大新银行
|
||||
DSBCN,大新银行(中国)
|
||||
DSBHK,大新银行(香港)
|
||||
DTCCB,大同银行
|
||||
DYCB,德阳商业银行
|
||||
DYCCB,东营市商业银行
|
||||
DZBANK,德州银行
|
||||
DZCBANK,达州银行
|
||||
|
||||
EGBANK,恒丰银行
|
||||
ERB,龙岗鼎业村镇银行
|
||||
ESRCB,恩施农村商业银行
|
||||
|
||||
FBBANK,富邦华一银行
|
||||
FDB,富滇银行
|
||||
FJHXBC,福建海峡银行
|
||||
FJNX,福建省农村信用社联合社
|
||||
FMBANK,吉林丰满惠民村镇银行
|
||||
FSCB,抚顺银行
|
||||
FSCCB,抚顺银行股份有限公司
|
||||
FXCB,阜新银行
|
||||
|
||||
GCB,广州银行
|
||||
GDB,广东发展银行
|
||||
GDRCC,广东省农村信用社联合社
|
||||
GHB,广东华兴银行
|
||||
GLBANK,桂林银行
|
||||
GRCB,广州农商银行
|
||||
GSBANK,甘肃银行
|
||||
GSRCU,甘肃省农村信用社
|
||||
GXHMVB,长春高新惠民村镇银行
|
||||
GXRCU,广西省农村信用社
|
||||
GYCB,贵阳市商业银行
|
||||
GZB,赣州银行
|
||||
GZRCU,贵州省农村信用社
|
||||
|
||||
H3CB,内蒙古银行
|
||||
HANABANK,韩亚银行
|
||||
HBC,湖北银行
|
||||
HBHSBANK,湖北银行黄石分行
|
||||
HBRCU,河北省农村信用社
|
||||
HBYCBANK,湖北银行宜昌分行
|
||||
HDBANK,邯郸银行
|
||||
HDHMCB,惠东惠民村镇银行
|
||||
HKB,汉口银行
|
||||
HKBEA,东亚银行
|
||||
HLDB,葫芦岛市商业银行
|
||||
HLDCCB,葫芦岛市商业银行
|
||||
HLJRCU,黑龙江省农村信用社
|
||||
HNRCC,湖南省农村信用社
|
||||
HNRCU,河南省农村信用社
|
||||
HRBANK,哈尔滨银行
|
||||
HRXJB,华融湘江银行
|
||||
HSB,恒生银行
|
||||
HSBANK,徽商银行
|
||||
HSBC,汇丰银行(中国)
|
||||
HSBK,衡水银行
|
||||
HURCB,湖北省农村信用社
|
||||
HXBANK,华夏银行
|
||||
HZCB,杭州银行
|
||||
HZCCB,湖州市商业银行
|
||||
|
||||
ICBC,中国工商银行
|
||||
|
||||
JHBANK,金华银行
|
||||
JINCHB,晋城银行
|
||||
JJBANK,九江银行
|
||||
JLBANK,吉林银行
|
||||
JLRCU,吉林农信
|
||||
JNBANK,济宁银行
|
||||
JRCB,江苏江阴农村商业银行
|
||||
JSB,晋商银行
|
||||
JSBANK,江苏银行
|
||||
JSRCU,江苏省农村信用联合社
|
||||
JXBANK,嘉兴银行
|
||||
JXRCU,江西省农村信用社
|
||||
JZBANK,晋中市商业银行
|
||||
JZCBANK,焦作市商业银行
|
||||
|
||||
KLB,昆仑银行
|
||||
KMRCU,昆明农村信用联合社
|
||||
KORLABANK,库尔勒市商业银行
|
||||
KSRB,昆山农村商业银行
|
||||
KSRCB,昆山农信社
|
||||
|
||||
LANGFB,廊坊银行
|
||||
LNRCC,辽宁省农村信用社
|
||||
LSB,临商银行
|
||||
LSBANK,莱商银行
|
||||
LSBC,临商银行
|
||||
LSCCB,乐山市商业银行
|
||||
LSZRCB,凉山州商业银行
|
||||
LUZBANK,泸州市商业银行
|
||||
LYBANK,洛阳银行
|
||||
LYCB,辽阳市商业银行
|
||||
LZCCB,柳州银行
|
||||
LZYH,兰州银行
|
||||
|
||||
MTBANK,浙江民泰商业银行
|
||||
MYBANK,绵阳市商业银行
|
||||
|
||||
NBBANK,宁波银行
|
||||
NBYZ,鄞州银行
|
||||
NCB,江西银行
|
||||
NCBANK,宁波通商银行
|
||||
NDHB,宁波东海银行
|
||||
NHB,南海农商银行
|
||||
NHQS,农信银清算中心
|
||||
NJCB,南京银行
|
||||
NMGNXS,内蒙古农村信用社
|
||||
NTCCB,南通商业银行
|
||||
NXBANK,宁夏银行
|
||||
NXRCU,宁夏黄河农村商业银行
|
||||
NYBANK,广东南粤银行
|
||||
NYCB,南阳村镇银行
|
||||
NYNB,广东南粤银行
|
||||
|
||||
OCBC,华侨银行(中国)
|
||||
ORBANK,鄂尔多斯银行
|
||||
|
||||
PLCCB,平凉市商业银行
|
||||
PSBC,中国邮政储蓄银行
|
||||
PZBANK,盘锦市商业银行
|
||||
PZHCCB,攀枝花市商业银行
|
||||
|
||||
QDCCB,青岛银行
|
||||
QDRCB,青岛农村商业银行
|
||||
QHDBANK,秦皇岛银行
|
||||
QHDCCB,秦皇岛市商业银行
|
||||
QHRC,青海农村信用社
|
||||
QJCCB,曲靖市商业银行
|
||||
QLBANK,齐鲁银行
|
||||
QLCZYH,齐鲁村镇银行
|
||||
|
||||
RBOZ,珠海华润银行
|
||||
RXCB,榆次融信村镇银行
|
||||
RZB,日照银行
|
||||
RZCCB,日照银行
|
||||
|
||||
SCB,渣打银行
|
||||
SCBHK,渣打银行(香港)
|
||||
SCCB,三门峡银行
|
||||
SCRCU,四川省农村信用社
|
||||
SDEB,顺德农商银行
|
||||
SDRCU,山东省农村信用社
|
||||
SHBANK,上海银行
|
||||
SHCBHK,上海商业银行(香港)
|
||||
SHRCB,上海农村商业银行
|
||||
SJBANK,盛京银行
|
||||
SLH,湖南农村信用社联合社
|
||||
SLRCB,双流诚民村镇银行
|
||||
SNCCB,遂宁市商业银行
|
||||
SPABANK,平安银行
|
||||
SPDB,上海浦东发展银行
|
||||
SRBANK,上饶银行
|
||||
SRCB,深圳农村商业银行
|
||||
SXCB,绍兴银行
|
||||
SXRCCU,陕西信合
|
||||
SXRCU,山西省农村信用社
|
||||
SZSBK,石嘴山银行
|
||||
|
||||
TACCB,泰安市商业银行
|
||||
TCCB,天津银行
|
||||
TCRCB,江苏太仓农村商业银行
|
||||
TFB,大丰银行有限公司
|
||||
TJBHB,天津滨海农村商业银行
|
||||
TLBANK,铁岭银行
|
||||
TRCB,天津农商银行
|
||||
TSBANK,唐山银行
|
||||
TZCB,台州银行
|
||||
|
||||
URB,联合村镇银行
|
||||
URMQCCB,乌鲁木齐市商业银行
|
||||
|
||||
WHB,永亨银行
|
||||
WHBANK,乌海银行
|
||||
WHBMA,澳门永亨银行
|
||||
WHCCB,威海市商业银行
|
||||
WHRCB,武汉农村商业银行
|
||||
WJRCB,吴江农商银行
|
||||
WLB,永隆银行
|
||||
WLBHK,永隆银行
|
||||
WOORI,友利银行(中国)
|
||||
WRCB,无锡农村商业银行
|
||||
WXCCB,无锡市商业银行
|
||||
WZCB,温州银行
|
||||
|
||||
XABANK,西安银行
|
||||
XCYH,许昌银行
|
||||
XFRCB,咸丰常农商村镇银行
|
||||
XHCZYH,新华村镇银行
|
||||
XHRCB,新会农商银行
|
||||
XJRCU,新疆农村信用社
|
||||
XLBANK,中山小榄村镇银行
|
||||
XMBANK,厦门银行
|
||||
XMCCB,厦门市商业银行
|
||||
XTB,邢台银行
|
||||
XXBANK,新乡银行
|
||||
XYBANK,信阳银行
|
||||
|
||||
YACCB,雅安市商业银行
|
||||
YBCCB,宜宾市商业银行
|
||||
YCCB,宜昌市商业银行
|
||||
YCCCB,盐城商行
|
||||
YDNSCZYH,尧都农商村镇银行
|
||||
YDRCB,尧都农商行
|
||||
YKYHCCB,营口沿海银行
|
||||
YNRCC,云南省农村信用社
|
||||
YQCCB,阳泉银行
|
||||
YTBANK,烟台银行
|
||||
YXCCB,玉溪市商业银行
|
||||
YZBANK,银座银行
|
||||
|
||||
ZBCB,齐商银行
|
||||
ZGCCB,自贡市商业银行
|
||||
ZHCCB,珠海华润银行股份有限公司
|
||||
ZJCCB,镇江市商业银行
|
||||
ZJKCCB,张家口市商业银行
|
||||
ZJNX,浙江省农村信用社联合社
|
||||
ZJTLCB,浙江泰隆商业银行
|
||||
ZRCBANK,张家港农村商业银行
|
||||
ZYB,中原银行
|
||||
ZYCBANK,遵义市商业银行
|
||||
ZZBANK,郑州银行
|
||||
ZZCCB,郑州商业银行
|
||||
|
54
bank_card/validator.go
Normal file
54
bank_card/validator.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package bank_card
|
||||
|
||||
// IsValidLuhn 使用Luhn算法校验银行卡号码
|
||||
// @see https://en.wikipedia.org/wiki/Luhn_algorithm
|
||||
// @see https://www.geeksforgeeks.org/luhn-algorithm/
|
||||
// @see https://medium.com/@akshaymohite/luhns-algorithm-to-validate-credit-debit-card-numbers-1952e6c7a9d0
|
||||
// @see https://www.woshipm.com/pd/371041.html
|
||||
func IsValidLuhn(cardNo string) bool {
|
||||
length := len(cardNo)
|
||||
if length == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if !isNumberString(cardNo) {
|
||||
return false
|
||||
}
|
||||
|
||||
sum := 0
|
||||
second := false
|
||||
for i := length - 1; i >= 0; i-- {
|
||||
d := cardNo[i] - '0'
|
||||
|
||||
if second == true {
|
||||
d = d * 2
|
||||
}
|
||||
|
||||
sum += int(d) / 10
|
||||
sum += int(d) % 10
|
||||
|
||||
second = !second
|
||||
}
|
||||
|
||||
return sum%10 == 0
|
||||
}
|
||||
|
||||
// IsValidBankCardNo 是否合法的银行卡号
|
||||
func IsValidBankCardNo(cardNo string) bool {
|
||||
length := len(cardNo)
|
||||
if length < 12 || length > 19 {
|
||||
return false
|
||||
}
|
||||
return IsValidLuhn(cardNo)
|
||||
}
|
||||
|
||||
// isNumberString 验证字符是数字
|
||||
func isNumberString(s string) bool {
|
||||
length := len(s)
|
||||
for i := 0; i < length; i++ {
|
||||
if s[i] < '0' || s[i] > '9' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
106
bank_card/validator_test.go
Normal file
106
bank_card/validator_test.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package bank_card
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsValidLuhn(t *testing.T) {
|
||||
var validBankCards = []string{
|
||||
"79927398713",
|
||||
"6226095711989751",
|
||||
"49927398716",
|
||||
"1234567812345670",
|
||||
"356938035643809",
|
||||
"1111222233334444",
|
||||
"374652346956782346957823694857692364857368475368",
|
||||
"6228480402564890018",
|
||||
"6228480402637874213",
|
||||
"6228481552887309119",
|
||||
"6228480801416266113",
|
||||
"6228481698729890079",
|
||||
"6222081106004039591",
|
||||
}
|
||||
|
||||
var invalidBankCards = []string{
|
||||
"49927398717",
|
||||
"1234567812345678",
|
||||
"314143525252",
|
||||
"534618613411236",
|
||||
"1234567879855431",
|
||||
"374652346956782346957823694857692364857387456834",
|
||||
"79927398710",
|
||||
"79927398711",
|
||||
"79927398711",
|
||||
"79927398712",
|
||||
"79927398714",
|
||||
"79927398715",
|
||||
"79927398716",
|
||||
"79927398717",
|
||||
"79927398718",
|
||||
"79927398719",
|
||||
"621661280000447287",
|
||||
}
|
||||
|
||||
for _, w := range validBankCards {
|
||||
t.Run("valid bank card: "+w, func(t *testing.T) {
|
||||
assert.True(t, IsValidLuhn(w))
|
||||
})
|
||||
}
|
||||
|
||||
for _, w := range invalidBankCards {
|
||||
t.Run("invalid bank card: "+w, func(t *testing.T) {
|
||||
assert.False(t, IsValidLuhn(w))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidBankCardNo(t *testing.T) {
|
||||
var validBankCards = []string{
|
||||
"6226095711989751",
|
||||
"6228480402564890018",
|
||||
"6228480402637874213",
|
||||
"6228481552887309119",
|
||||
"6228480801416266113",
|
||||
"6228481698729890079",
|
||||
"6222081106004039591",
|
||||
"1234567812345670",
|
||||
"356938035643809",
|
||||
"1111222233334444",
|
||||
}
|
||||
|
||||
var invalidBankCards = []string{
|
||||
"49927398717",
|
||||
"1234567812345678",
|
||||
"314143525252",
|
||||
"534618613411236",
|
||||
"1234567879855431",
|
||||
"374652346956782346957823694857692364857387456834",
|
||||
"79927398710",
|
||||
"79927398711",
|
||||
"79927398711",
|
||||
"79927398712",
|
||||
"79927398714",
|
||||
"79927398715",
|
||||
"79927398716",
|
||||
"79927398717",
|
||||
"79927398718",
|
||||
"79927398719",
|
||||
"621661280000447287",
|
||||
"79927398713",
|
||||
"49927398716",
|
||||
"374652346956782346957823694857692364857368475368",
|
||||
}
|
||||
|
||||
for _, w := range validBankCards {
|
||||
t.Run("valid bank card: "+w, func(t *testing.T) {
|
||||
assert.True(t, IsValidBankCardNo(w))
|
||||
})
|
||||
}
|
||||
|
||||
for _, w := range invalidBankCards {
|
||||
t.Run("invalid bank card: "+w, func(t *testing.T) {
|
||||
assert.False(t, IsValidBankCardNo(w))
|
||||
})
|
||||
}
|
||||
}
|
||||
18
geoip/go.mod
Normal file
18
geoip/go.mod
Normal file
@@ -0,0 +1,18 @@
|
||||
module github.com/tx7do/kratos-utils/geoip
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/go-kratos/kratos/v2 v2.7.0
|
||||
github.com/oschwald/geoip2-golang v1.9.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.11.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
23
geoip/go.sum
Normal file
23
geoip/go.sum
Normal file
@@ -0,0 +1,23 @@
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-kratos/kratos/v2 v2.7.0 h1:9DaVgU9YoHPb/BxDVqeVlVCMduRhiSewG3xE+e9ZAZ8=
|
||||
github.com/go-kratos/kratos/v2 v2.7.0/go.mod h1:CPn82O93OLHjtnbuyOKhAG5TkSvw+mFnL32c4lZFDwU=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
|
||||
github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y=
|
||||
github.com/oschwald/maxminddb-golang v1.11.0 h1:aSXMqYR/EPNjGE8epgqwDay+P30hCBZIveY0WZbAWh0=
|
||||
github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
7
go.mod
7
go.mod
@@ -5,9 +5,7 @@ go 1.20
|
||||
require (
|
||||
entgo.io/contrib v0.4.5
|
||||
entgo.io/ent v0.12.4
|
||||
github.com/go-kratos/kratos/v2 v2.7.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/oschwald/geoip2-golang v1.9.0
|
||||
github.com/sony/sonyflake v1.2.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
golang.org/x/crypto v0.13.0
|
||||
@@ -24,16 +22,19 @@ require (
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.18.0 // indirect
|
||||
github.com/jhump/protoreflect v1.15.2 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/zclconf/go-cty v1.14.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.13.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
18
go.sum
18
go.sum
@@ -11,10 +11,9 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY=
|
||||
github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-kratos/kratos/v2 v2.7.0 h1:9DaVgU9YoHPb/BxDVqeVlVCMduRhiSewG3xE+e9ZAZ8=
|
||||
github.com/go-kratos/kratos/v2 v2.7.0/go.mod h1:CPn82O93OLHjtnbuyOKhAG5TkSvw+mFnL32c4lZFDwU=
|
||||
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
||||
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
@@ -30,21 +29,25 @@ github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHL
|
||||
github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
|
||||
github.com/jhump/protoreflect v1.15.2 h1:7YppbATX94jEt9KLAc5hICx4h6Yt3SaavhQRsIUEHP0=
|
||||
github.com/jhump/protoreflect v1.15.2/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
|
||||
github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sony/sonyflake v1.2.0 h1:Pfr3A+ejSg+0SPqpoAmQgEtNDAhc2G1SUYk205qVMLQ=
|
||||
github.com/sony/sonyflake v1.2.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y=
|
||||
@@ -67,8 +70,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto v0.0.0-20230629202037-9506855d4529 h1:9JucMWR7sPvCxUFd6UsOUNmA5kCcWOfORaT3tpAsKQs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 h1:DEH99RbiLZhMxrpEJCZ0A+wdTe0EOgou/poSLx9vWf4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
@@ -76,5 +79,6 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
Reference in New Issue
Block a user