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}