credit_cards.go

 1package fake
 2
 3import (
 4	"strings"
 5
 6	"strconv"
 7)
 8
 9type creditCard struct {
10	vendor   string
11	length   int
12	prefixes []int
13}
14
15var creditCards = map[string]creditCard{
16	"visa":       {"VISA", 16, []int{4539, 4556, 4916, 4532, 4929, 40240071, 4485, 4716, 4}},
17	"mastercard": {"MasterCard", 16, []int{51, 52, 53, 54, 55}},
18	"amex":       {"American Express", 15, []int{34, 37}},
19	"discover":   {"Discover", 16, []int{6011}},
20}
21
22// CreditCardType returns one of the following credit values:
23// VISA, MasterCard, American Express and Discover
24func CreditCardType() string {
25	n := len(creditCards)
26	var vendors []string
27	for _, cc := range creditCards {
28		vendors = append(vendors, cc.vendor)
29	}
30
31	return vendors[r.Intn(n)]
32}
33
34// CreditCardNum generated credit card number according to the card number rules
35func CreditCardNum(vendor string) string {
36	if vendor != "" {
37		vendor = strings.ToLower(vendor)
38	} else {
39		var vendors []string
40		for v := range creditCards {
41			vendors = append(vendors, v)
42		}
43		vendor = vendors[r.Intn(len(vendors))]
44	}
45	card := creditCards[vendor]
46	prefix := strconv.Itoa(card.prefixes[r.Intn(len(card.prefixes))])
47	num := []rune(prefix)
48	for i := 0; i < card.length-len(prefix); i++ {
49		num = append(num, genCCDigit(num))
50	}
51	return string(num)
52}
53
54func genCCDigit(num []rune) rune {
55	sum := 0
56	for i := len(num) - 1; i >= 0; i-- {
57		n := int(num[i])
58		if i%2 != 0 {
59			sum += n
60		} else {
61			if n*2 > 9 {
62				sum += n*2 - 9
63			} else {
64				sum += n * 2
65			}
66		}
67	}
68	return rune(((sum/10+1)*10 - sum) % 10)
69}