134 lines
2.7 KiB
Go
134 lines
2.7 KiB
Go
package charsets
|
|
|
|
import "strings"
|
|
|
|
type RandInt interface {
|
|
Int() int
|
|
}
|
|
|
|
type Charset interface {
|
|
TestRune(char rune) bool
|
|
RandomRune(r RandInt) rune
|
|
RandomString(r RandInt, size int) string
|
|
}
|
|
|
|
func NewCharsetFromASCII(offset, size int) Charset {
|
|
return charsetASCII{offset: offset, size: size}
|
|
}
|
|
|
|
type charsetASCII struct {
|
|
offset int
|
|
size int
|
|
}
|
|
|
|
func (c charsetASCII) TestRune(char rune) bool {
|
|
return int(char) >= c.offset && int(char) < c.offset+c.size
|
|
}
|
|
|
|
func (c charsetASCII) RandomRune(r RandInt) rune {
|
|
num := c.offset + r.Int()%(c.size-1)
|
|
return rune(num)
|
|
}
|
|
|
|
func (c charsetASCII) RandomString(r RandInt, size int) string {
|
|
builder := strings.Builder{}
|
|
for i := 0; i < size; i++ {
|
|
builder.WriteRune(c.RandomRune(r))
|
|
}
|
|
return builder.String()
|
|
}
|
|
|
|
// func (c charsetASCII) String() string {
|
|
// builder := strings.Builder{}
|
|
// for i := 0; i < c.size; i++ {
|
|
// builder.WriteRune(rune(c.offset + i))
|
|
// }
|
|
// return builder.String()
|
|
// }
|
|
|
|
func NewCharsetFromString(s string) Charset {
|
|
charsArray := make([]rune, len(s))
|
|
charsMap := make(map[rune]bool, len(s))
|
|
for i, v := range s {
|
|
charsArray[i] = v
|
|
charsMap[v] = true
|
|
}
|
|
|
|
return charsetFromString{
|
|
charsArray: charsArray,
|
|
charsMap: charsMap,
|
|
}
|
|
}
|
|
|
|
type charsetFromString struct {
|
|
charsMap map[rune]bool
|
|
charsArray []rune
|
|
}
|
|
|
|
func (c charsetFromString) TestRune(char rune) bool {
|
|
return c.charsMap[char]
|
|
}
|
|
|
|
func (c charsetFromString) RandomRune(r RandInt) rune {
|
|
num := r.Int() % (len(c.charsArray) - 1)
|
|
return c.charsArray[num]
|
|
}
|
|
|
|
func (c charsetFromString) RandomString(r RandInt, size int) string {
|
|
builder := strings.Builder{}
|
|
for i := 0; i < size; i++ {
|
|
builder.WriteRune(c.RandomRune(r))
|
|
}
|
|
return builder.String()
|
|
}
|
|
|
|
// func (c charsetFromString) String() string {
|
|
// builder := strings.Builder{}
|
|
// for _, v := range c.charsArray {
|
|
// builder.WriteRune(v)
|
|
// }
|
|
// return builder.String()
|
|
// }
|
|
|
|
func NewCharsetUnion(opts ...Charset) Charset {
|
|
charsets := []Charset{}
|
|
return charsetUnion{
|
|
charsets: append(charsets, opts...),
|
|
}
|
|
}
|
|
|
|
type charsetUnion struct {
|
|
charsets []Charset
|
|
}
|
|
|
|
func (c charsetUnion) TestRune(char rune) bool {
|
|
for _, charset := range c.charsets {
|
|
if charset.TestRune(char) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (c charsetUnion) RandomRune(r RandInt) rune {
|
|
index := r.Int() % (len(c.charsets) - 1)
|
|
charset := c.charsets[index]
|
|
|
|
return charset.RandomRune(r)
|
|
}
|
|
|
|
func (c charsetUnion) RandomString(r RandInt, size int) string {
|
|
// TODO: improve distribution
|
|
builder := strings.Builder{}
|
|
for i := 0; i < size; i++ {
|
|
index := r.Int() % (len(c.charsets) - 1)
|
|
charset := c.charsets[index]
|
|
builder.WriteRune(charset.RandomRune(r))
|
|
}
|
|
return builder.String()
|
|
}
|
|
|
|
// func (c charsetUnion) String() string {
|
|
// return ""
|
|
// }
|