-
Notifications
You must be signed in to change notification settings - Fork 1
/
charset.go
104 lines (84 loc) · 2.94 KB
/
charset.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
98
99
100
101
102
103
104
package passit
import (
"io"
"unicode"
"unicode/utf8"
"golang.org/x/exp/utf8string"
)
type asciiGenerator struct{ s string }
// Digit is a Generator that returns a random numeric digit.
var Digit Generator = &asciiGenerator{"0123456789"}
// LatinLower is a Generator that returns a random lowercase character from the latin
// alphabet.
var LatinLower Generator = &asciiGenerator{"abcdefghijklmnopqrstuvwxyz"}
// LatinUpper is a Generator that returns a random uppercase character from the latin
// alphabet.
var LatinUpper Generator = &asciiGenerator{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}
// LatinMixed is a Generator that returns a random mixed-case characters from the
// latin alphabet.
var LatinMixed Generator = &asciiGenerator{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"}
// LatinLowerDigit is a Generator that returns a random lowercase character from the
// latin alphabet or a numeric digit.
var LatinLowerDigit Generator = &asciiGenerator{"abcdefghijklmnopqrstuvwxyz0123456789"}
// LatinUpperDigit is a Generator that returns a random uppercase character from the
// latin alphabet or a numeric digit.
var LatinUpperDigit Generator = &asciiGenerator{"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"}
// LatinMixedDigit is a Generator that returns a random mixed-case characters from
// the latin alphabet or a numeric digit.
var LatinMixedDigit Generator = &asciiGenerator{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"}
func (ag *asciiGenerator) Password(r io.Reader) (string, error) {
idx, err := readIntN(r, len(ag.s))
if err != nil {
return "", err
}
return ag.s[idx : idx+1], nil
}
type runeGenerator struct{ s utf8string.String }
// FromCharset returns a Generator that returns a random rune from charset.
func FromCharset(charset string) Generator {
switch utf8.RuneCountInString(charset) {
case 0:
return Empty
case 1:
return String(charset)
default:
var rg runeGenerator
rg.s.Init(charset)
return &rg
}
}
func (rg *runeGenerator) Password(r io.Reader) (string, error) {
idx, err := readIntN(r, rg.s.RuneCount())
if err != nil {
return "", err
}
return rg.s.Slice(idx, idx+1), nil
}
type unicodeGenerator struct {
tab *unicode.RangeTable
runes int
}
// FromRangeTable returns a Generator that returns a random rune from the
// unicode.RangeTable.
//
// The returned Generator is only deterministic if the same unicode.RangeTable is
// used. Be aware that the builtin unicode.X tables are subject to change as new
// versions of Unicode are released and are not suitable for deterministic use.
func FromRangeTable(tab *unicode.RangeTable) Generator {
runes := countRunesInTable(tab)
switch runes {
case 0:
return Empty
case 1:
return String(string(getRuneInTable(tab, 0)))
default:
return &unicodeGenerator{tab, runes}
}
}
func (ug *unicodeGenerator) Password(r io.Reader) (string, error) {
idx, err := readIntN(r, ug.runes)
if err != nil {
return "", err
}
return string(getRuneInTable(ug.tab, idx)), nil
}