-
Notifications
You must be signed in to change notification settings - Fork 0
/
bban.go
83 lines (70 loc) · 1.54 KB
/
bban.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package bban
import (
"math"
"math/rand"
"strconv"
"strings"
)
// Mods can be used during validation & generation
const (
DoubleMod int = iota
Mod10
Mod11
)
// Random generates random bban number based on sort code, weights and mod.
func Random(sortCode, weights string, mod int) string {
exp := len(weights) - len(sortCode)
for {
rand := strconv.Itoa(rand.Intn(int(math.Pow10(exp)) - 1))
if Validate(sortCode, rand, weights, mod) {
return rand
}
}
}
// Next try to find next account in a row, using sort code, previous account number, weights and mod
func Next(sortCode, account, weights string, mod int) string {
exp := len(weights) - len(sortCode)
acc, _ := strconv.Atoi(account)
for {
acc++
tmp := strconv.Itoa(acc)
if len(tmp) < exp {
tmp = strings.Repeat("0", exp-len(tmp)) + tmp
}
if Validate(sortCode, tmp, weights, mod) {
return tmp
}
}
}
// Validate validate account number based on sort code and weights with mod
func Validate(sortCode, account, weights string, mod int) bool {
bban := sortCode + account
if len(bban) != len(weights) {
return false
}
var (
mul string
res int
)
for i := 0; i < len(bban); i++ {
x, _ := strconv.Atoi(string(bban[i]))
y, _ := strconv.Atoi(string(weights[i]))
mul += strconv.Itoa(x * y)
res += x * y
}
switch mod {
case DoubleMod:
var sum int
for i := 0; i < len(mul); i++ {
x, _ := strconv.Atoi(string(mul[i]))
sum += x
}
return sum%10 == 0
case Mod10:
return res%10 == 0
case Mod11:
return res%11 == 0
default:
return false
}
}