forked from hanguofeng/gocaptcha
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wordmanager.go
104 lines (89 loc) · 2.04 KB
/
wordmanager.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
// Copyright 2013 hanguofeng. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gocaptcha
import (
"encoding/csv"
"errors"
"io"
"os"
"strings"
"unicode/utf8"
)
//WordManager is a captcha word manage tool
type WordManager struct {
words []string
isDataSingleChar bool
isValid bool
}
//CreateWordManagerFromDataFile will create a entity from a dictionary file
func CreateWordManagerFromDataFile(filename string) (*WordManager, error) {
mgr := &WordManager{}
mgr.words = []string{}
mgr.isValid = false
f, err := os.Open(filename)
if nil != err {
return mgr, err
}
defer f.Close()
reader := csv.NewReader(f)
mgr.isDataSingleChar = true
for {
record, err := reader.Read()
if err == io.EOF {
break
} else if nil != err {
return mgr, err
}
if 1 < len([]rune(record[0])) {
mgr.isDataSingleChar = false
}
mgr.words = append(mgr.words, strings.TrimSpace(record[0]))
}
mgr.isValid = true
return mgr, nil
}
//Get a specifical length word
func (mgr *WordManager) Get(length int) (string, error) {
var retErr error
rst := ""
if mgr.isValid {
if true == mgr.isDataSingleChar {
if len(mgr.words) < length {
return "", errors.New("dict words count is less than your length")
}
for {
line := mgr.getLine()
if false == strings.ContainsRune(rst, []rune(line)[0]) {
rst = rst + line
}
if utf8.RuneCountInString(rst) >= length {
break
}
}
rstRune := []rune(rst)
rst = string(rstRune[0:length])
} else {
rst = mgr.getLine()
}
} else {
retErr = errors.New("WordManager is invalid")
}
return rst, retErr
}
func (mgr *WordManager) SetWords(words []string) {
mgr.words = words
mgr.isValid = len(words) > 0
mgr.isDataSingleChar = true
for _, s := range words {
if len([]rune(s)) > 1 {
mgr.isDataSingleChar = false
}
}
}
func (mgr *WordManager) getLine() string {
maxIndex := len(mgr.words) - 1
rstIndex := rnd(0, maxIndex)
rst := mgr.words[rstIndex]
return rst
}