-
Notifications
You must be signed in to change notification settings - Fork 1
/
name_generator.go
97 lines (84 loc) · 2.28 KB
/
name_generator.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package qbin
import (
"crypto/rand"
"crypto/sha256"
"database/sql"
"encoding/hex"
"errors"
"io/ioutil"
"math/big"
"strings"
)
var words = []string{}
var characters = strings.Split("abcdefghijklmnopqrstuvwxyz0123456789", "")
func randomWord(array []string, try int, err error) string {
if try > 10 {
// We somehow tried 10 times to get a random value and it failed every time. Something is extremely wrong here.
Log.Errorf("crypto/rand issue - something is probably extremely wrong! %s", err)
panic(err)
}
i, err := rand.Int(rand.Reader, big.NewInt(int64(len(array))))
if err != nil {
return randomWord(array, try+1, err)
}
return array[i.Int64()]
}
// LoadWordsFile imports the word definition file used for names.
func LoadWordsFile(filename string) error {
content, err := ioutil.ReadFile(filename)
if err == nil {
source := strings.Split(string(content), "\n")
words = make([]string, 0)
for _, word := range source {
word = strings.ToLower(strings.TrimSpace(word))
if len(word) > 0 && !strings.HasPrefix(word, "#") {
words = append(words, word)
}
}
if len(words) == 0 {
return errors.New("file doesn't contain any words")
}
Log.Debugf("%d words loaded.", len(words))
}
return err
}
// GenerateName generates a slug in the format "cornflake-peddling-bp0q". Note that this function will return an empty string if an error occurs along the way!
func GenerateName() string {
text := ""
var word string
for i := 0; i < 6; i++ {
if i < 2 && len(words) > 0 {
word = randomWord(words, 0, nil)
} else {
word = randomWord(characters, 0, nil)
}
if i < 3 && len(words) > 0 {
text += "-" + word
} else {
text += word
}
}
return strings.TrimPrefix(text, "-")
}
var safeName *sql.Stmt
var errSafeName = errors.New("not initialized")
// GenerateSafeName generates a slug (like GenerateName()) that doesn't exist in the database yet.
func GenerateSafeName() (string, error) {
if errSafeName != nil {
return "", errSafeName
}
name := ""
rows := 1
for rows > 0 {
name = GenerateName()
if name == "" {
return "", errors.New("name generation failed")
}
databaseID := sha256.Sum256([]byte(name))
err := safeName.QueryRow(hex.EncodeToString(databaseID[:])).Scan(&rows)
if err != nil {
return "", err
}
}
return name, nil
}