Skip to content

Commit c0235a2

Browse files
committed
refactor sequencer into sub-package
1 parent 40cf7bc commit c0235a2

17 files changed

+190
-164
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
default: test
44

55
bench:
6-
go test -bench=. -benchmem ./passphrase ./password
6+
go test -bench=. -benchmem ./passphrase ./password ./password/sequencer
77

88
cyclo:
99
gocyclo -over 13 ./*/*.go

README.md

+31-24
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Passphrase & Password generation library for GoLang.
99

1010
## Passphrases
1111
```golang
12-
generator, err := passphrase.NewGenerator(
12+
g, err := passphrase.NewGenerator(
1313
passphrase.WithCapitalizedWords(true),
1414
passphrase.WithDictionary(dictionaries.English()),
1515
passphrase.WithNumWords(3),
@@ -21,7 +21,7 @@ Passphrase & Password generation library for GoLang.
2121
panic(err.Error())
2222
}
2323
for idx := 1; idx <= 10; idx++ {
24-
fmt.Printf("Passphrase #%3d: %#v\n", idx, generator.Generate())
24+
fmt.Printf("Passphrase #%3d: %#v\n", idx, g.Generate())
2525
}
2626
```
2727
<details>
@@ -42,8 +42,8 @@ Passphrase # 10: "Mirks6-Woofer-Lase"
4242

4343
## Passwords
4444
```golang
45-
generator, err := password.NewGenerator(
46-
password.WithCharset(password.AllChars.WithoutAmbiguity().WithoutDuplicates()),
45+
g, err := password.NewGenerator(
46+
password.WithCharset(charset.AllChars.WithoutAmbiguity().WithoutDuplicates()),
4747
password.WithLength(12),
4848
password.WithMinLowerCase(5),
4949
password.WithMinUpperCase(2),
@@ -53,7 +53,7 @@ Passphrase # 10: "Mirks6-Woofer-Lase"
5353
panic(err.Error())
5454
}
5555
for idx := 1; idx <= 10; idx++ {
56-
fmt.Printf("Password #%3d: %#v\n", idx, generator.Generate())
56+
fmt.Printf("Password #%3d: %#v\n", idx, g.Generate())
5757
}
5858
```
5959
<details>
@@ -75,20 +75,20 @@ Password # 10: "kmQVb&fPqexj"
7575
### Sequential Passwords
7676

7777
```golang
78-
sequencer, err := password.NewSequencer(
79-
password.WithCharset(password.AllChars.WithoutAmbiguity()),
80-
password.WithLength(8),
78+
s, err := sequencer.New(
79+
sequencer.WithCharset(charset.AllChars.WithoutAmbiguity()),
80+
sequencer.WithLength(8),
8181
)
8282
if err != nil {
8383
panic(err.Error())
8484
}
8585
for idx := 1; idx <= 10; idx++ {
86-
fmt.Printf("Password #%3d: %#v\n", idx, sequencer.Get())
86+
fmt.Printf("Password #%3d: %#v\n", idx, s.Get())
8787

88-
if !sequencer.HasNext() {
88+
if !s.HasNext() {
8989
break
9090
}
91-
sequencer.Next()
91+
s.Next()
9292
}
9393
```
9494
<details>
@@ -109,9 +109,9 @@ Password # 10: "AAAAAAAK"
109109

110110
#### Streamed (for async processing)
111111
```golang
112-
sequencer, err := password.NewSequencer(
113-
password.WithCharset(password.Charset("AB")),
114-
password.WithLength(4),
112+
s, err := sequencer.New(
113+
sequencer.WithCharset(charset.Charset("AB")),
114+
sequencer.WithLength(4),
115115
)
116116
if err != nil {
117117
panic(err.Error())
@@ -122,7 +122,7 @@ Password # 10: "AAAAAAAK"
122122

123123
chPasswords := make(chan string, 1)
124124
go func() {
125-
err := sequencer.Stream(ctx, chPasswords)
125+
err := s.Stream(ctx, chPasswords)
126126
if err != nil {
127127
panic(err.Error())
128128
}
@@ -170,20 +170,27 @@ goos: linux
170170
goarch: amd64
171171
pkg: github.com/jedib0t/go-passwords/passphrase
172172
cpu: AMD Ryzen 9 5900X 12-Core Processor
173-
BenchmarkGenerator_Generate-12 2862954 393.5 ns/op 167 B/op 8 allocs/op
173+
BenchmarkGenerator_Generate-12 3015926 392.7 ns/op 167 B/op 8 allocs/op
174174
PASS
175-
ok github.com/jedib0t/go-passwords/passphrase 1.567s
175+
ok github.com/jedib0t/go-passwords/passphrase 1.603s
176176
177177
goos: linux
178178
goarch: amd64
179179
pkg: github.com/jedib0t/go-passwords/password
180180
cpu: AMD Ryzen 9 5900X 12-Core Processor
181-
BenchmarkGenerator_Generate-12 6413606 185.3 ns/op 40 B/op 2 allocs/op
182-
BenchmarkSequencer_GotoN-12 4353010 272.5 ns/op 32 B/op 3 allocs/op
183-
BenchmarkSequencer_Next-12 13955396 84.61 ns/op 16 B/op 1 allocs/op
184-
BenchmarkSequencer_NextN-12 6473270 183.9 ns/op 32 B/op 3 allocs/op
185-
BenchmarkSequencer_Prev-12 13106161 87.22 ns/op 16 B/op 1 allocs/op
186-
BenchmarkSequencer_PrevN-12 3967755 288.8 ns/op 32 B/op 3 allocs/op
181+
BenchmarkGenerator_Generate-12 6263398 187.5 ns/op 40 B/op 2 allocs/op
187182
PASS
188-
ok github.com/jedib0t/go-passwords/password 8.192s
183+
ok github.com/jedib0t/go-passwords/password 1.375s
184+
185+
goos: linux
186+
goarch: amd64
187+
pkg: github.com/jedib0t/go-passwords/password/sequencer
188+
cpu: AMD Ryzen 9 5900X 12-Core Processor
189+
BenchmarkSequencer_GotoN-12 4355002 274.6 ns/op 32 B/op 3 allocs/op
190+
BenchmarkSequencer_Next-12 13614666 88.99 ns/op 16 B/op 1 allocs/op
191+
BenchmarkSequencer_NextN-12 6216072 187.2 ns/op 32 B/op 3 allocs/op
192+
BenchmarkSequencer_Prev-12 13569340 87.69 ns/op 16 B/op 1 allocs/op
193+
BenchmarkSequencer_PrevN-12 4230654 277.9 ns/op 32 B/op 3 allocs/op
194+
PASS
195+
ok github.com/jedib0t/go-passwords/password/sequencer 6.888s
189196
```

password/charset.go renamed to charset/charset.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package password
1+
package charset
22

33
import (
44
"math/rand"

password/charset_test.go renamed to charset/charset_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package password
1+
package charset
22

33
import (
44
"math/rand"

main.go

+17-15
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"fmt"
66
"time"
77

8+
"github.com/jedib0t/go-passwords/charset"
89
"github.com/jedib0t/go-passwords/passphrase"
910
"github.com/jedib0t/go-passwords/passphrase/dictionaries"
1011
"github.com/jedib0t/go-passwords/password"
12+
"github.com/jedib0t/go-passwords/password/sequencer"
1113
)
1214

1315
func main() {
@@ -29,7 +31,7 @@ func main() {
2931
}
3032

3133
func passphraseGenerator() {
32-
generator, err := passphrase.NewGenerator(
34+
g, err := passphrase.NewGenerator(
3335
passphrase.WithCapitalizedWords(true),
3436
passphrase.WithDictionary(dictionaries.English()),
3537
passphrase.WithNumWords(3),
@@ -41,13 +43,13 @@ func passphraseGenerator() {
4143
panic(err.Error())
4244
}
4345
for idx := 1; idx <= 10; idx++ {
44-
fmt.Printf("Passphrase #%3d: %#v\n", idx, generator.Generate())
46+
fmt.Printf("Passphrase #%3d: %#v\n", idx, g.Generate())
4547
}
4648
}
4749

4850
func passwordGenerator() {
49-
generator, err := password.NewGenerator(
50-
password.WithCharset(password.AllChars.WithoutAmbiguity().WithoutDuplicates()),
51+
g, err := password.NewGenerator(
52+
password.WithCharset(charset.AllChars.WithoutAmbiguity().WithoutDuplicates()),
5153
password.WithLength(12),
5254
password.WithMinLowerCase(5),
5355
password.WithMinUpperCase(2),
@@ -57,32 +59,32 @@ func passwordGenerator() {
5759
panic(err.Error())
5860
}
5961
for idx := 1; idx <= 10; idx++ {
60-
fmt.Printf("Password #%3d: %#v\n", idx, generator.Generate())
62+
fmt.Printf("Password #%3d: %#v\n", idx, g.Generate())
6163
}
6264
}
6365

6466
func passwordSequencer() {
65-
sequencer, err := password.NewSequencer(
66-
password.WithCharset(password.AllChars.WithoutAmbiguity()),
67-
password.WithLength(8),
67+
s, err := sequencer.New(
68+
sequencer.WithCharset(charset.AllChars.WithoutAmbiguity()),
69+
sequencer.WithLength(8),
6870
)
6971
if err != nil {
7072
panic(err.Error())
7173
}
7274
for idx := 1; idx <= 10; idx++ {
73-
fmt.Printf("Password #%3d: %#v\n", idx, sequencer.Get())
75+
fmt.Printf("Password #%3d: %#v\n", idx, s.Get())
7476

75-
if !sequencer.HasNext() {
77+
if !s.HasNext() {
7678
break
7779
}
78-
sequencer.Next()
80+
s.Next()
7981
}
8082
}
8183

8284
func passwordSequencerStreaming() {
83-
sequencer, err := password.NewSequencer(
84-
password.WithCharset(password.Charset("AB")),
85-
password.WithLength(4),
85+
s, err := sequencer.New(
86+
sequencer.WithCharset(charset.Charset("AB")),
87+
sequencer.WithLength(4),
8688
)
8789
if err != nil {
8890
panic(err.Error())
@@ -93,7 +95,7 @@ func passwordSequencerStreaming() {
9395

9496
chPasswords := make(chan string, 1)
9597
go func() {
96-
err := sequencer.Stream(ctx, chPasswords)
98+
err := s.Stream(ctx, chPasswords)
9799
if err != nil {
98100
panic(err.Error())
99101
}

passphrase/rules.go

+14-32
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package passphrase
33
import "github.com/jedib0t/go-passwords/passphrase/dictionaries"
44

55
// Rule controls how the Generator/Sequencer generates passwords.
6-
type Rule func(a any)
6+
type Rule func(g *generator)
77

88
var (
99
basicRules = []Rule{
@@ -18,59 +18,41 @@ var (
1818

1919
// WithCapitalizedWords ensures the words are Capitalized.
2020
func WithCapitalizedWords(enabled bool) Rule {
21-
return func(a any) {
22-
switch v := a.(type) {
23-
case *generator:
24-
v.capitalize = enabled
25-
}
21+
return func(g *generator) {
22+
g.capitalize = enabled
2623
}
2724
}
2825

2926
func WithDictionary(words []string) Rule {
30-
return func(a any) {
31-
switch v := a.(type) {
32-
case *generator:
33-
v.dictionary = words
34-
}
27+
return func(g *generator) {
28+
g.dictionary = words
3529
}
3630
}
3731

3832
// WithNumber injects a random number after one of the words in the passphrase.
3933
func WithNumber(enabled bool) Rule {
40-
return func(a any) {
41-
switch v := a.(type) {
42-
case *generator:
43-
v.withNumber = enabled
44-
}
34+
return func(g *generator) {
35+
g.withNumber = enabled
4536
}
4637
}
4738

4839
// WithNumWords sets the number of words in the passphrase.
4940
func WithNumWords(n int) Rule {
50-
return func(a any) {
51-
switch v := a.(type) {
52-
case *generator:
53-
v.numWords = n
54-
}
41+
return func(g *generator) {
42+
g.numWords = n
5543
}
5644
}
5745

5846
// WithSeparator sets up the delimiter to separate words.
5947
func WithSeparator(s string) Rule {
60-
return func(a any) {
61-
switch v := a.(type) {
62-
case *generator:
63-
v.separator = s
64-
}
48+
return func(g *generator) {
49+
g.separator = s
6550
}
6651
}
6752

6853
func WithWordLength(min, max int) Rule {
69-
return func(a any) {
70-
switch v := a.(type) {
71-
case *generator:
72-
v.wordLenMin = min
73-
v.wordLenMax = max
74-
}
54+
return func(g *generator) {
55+
g.wordLenMin = min
56+
g.wordLenMax = max
7557
}
7658
}

password/default_generator.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package password
22

3+
import "github.com/jedib0t/go-passwords/charset"
4+
35
var (
46
defaultGenerator, _ = NewGenerator(
5-
WithCharset(AllChars.WithoutAmbiguity()),
7+
WithCharset(charset.AllChars.WithoutAmbiguity()),
68
WithLength(12),
79
WithMinLowerCase(3),
810
WithMinUpperCase(1),

password/generator.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"sync"
66
"time"
77
"unicode"
8+
9+
"github.com/jedib0t/go-passwords/charset"
810
)
911

1012
var (
@@ -45,8 +47,8 @@ func NewGenerator(rules ...Rule) (Generator, error) {
4547
// split the charsets
4648
g.charsetCaseLower = filterRunes(g.charset, unicode.IsLower)
4749
g.charsetCaseUpper = filterRunes(g.charset, unicode.IsUpper)
48-
g.charsetNonSymbols = filterRunes(g.charset, func(r rune) bool { return !Symbols.Contains(r) })
49-
g.charsetSymbols = filterRunes(g.charset, Symbols.Contains)
50+
g.charsetNonSymbols = filterRunes(g.charset, func(r rune) bool { return !charset.Symbols.Contains(r) })
51+
g.charsetSymbols = filterRunes(g.charset, charset.Symbols.Contains)
5052

5153
// create a storage pool with enough objects to support enough parallelism
5254
g.pool = &sync.Pool{
@@ -111,6 +113,8 @@ func (g *generator) numSymbolsToGenerate() int {
111113
return 0
112114
}
113115

116+
func (g *generator) ruleEnforcer() {}
117+
114118
func (g *generator) sanitize() (Generator, error) {
115119
// validate the inputs
116120
if len(g.charset) == 0 {

0 commit comments

Comments
 (0)