Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f5bf9fb

Browse files
committedJun 18, 2022
added ValidBehaviorCaptcha
1 parent 994f223 commit f5bf9fb

File tree

7 files changed

+250
-6
lines changed

7 files changed

+250
-6
lines changed
 

‎README.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
# go-captcha
22
golang 验证码
3+
4+
5+
## Preview
6+
[](./previews/test.png)
7+
[](./previews/test_1.png)
8+
[](./previews/test_2.png)

‎alphabet.go

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package captcha
2+
3+
var Alphabets = "abcdefghijklmnopqrstuvwxyxABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
4+
5+
var CNChars = []string{
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+
}

‎canvas.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ import (
88
"image/color"
99
"image/draw"
1010
"math"
11-
"unicode/utf8"
12-
1311
"math/rand"
1412
"time"
13+
"unicode/utf8"
1514
)
1615

1716
//go:embed fonts/*
@@ -178,7 +177,8 @@ func (c *Canvas) DrawString(text string) []DrawRect {
178177
var drawRects []DrawRect
179178
textPos := c.getFontPostions(text)
180179

181-
for index, ch := range text {
180+
var index = 0
181+
for _, ch := range text {
182182

183183
pos := textPos[index]
184184

@@ -217,6 +217,8 @@ func (c *Canvas) DrawString(text string) []DrawRect {
217217

218218
drawRects = append(drawRects, dp)
219219

220+
index = index + 1
221+
220222
}
221223

222224
return drawRects
@@ -415,4 +417,4 @@ func (c *Canvas) DrawCircle(xc, yc, r int, fill bool, cc color.Color) {
415417
}
416418
x++
417419
}
418-
}
420+
}

‎captcha.go

+58-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"image"
99
"image/color"
1010
"image/png"
11+
"math/rand"
1112
"os"
1213
)
1314

@@ -94,6 +95,7 @@ func (cp *Captcha) SetBackgroundColor(color color.Color) {
9495
cp.Config.BackgroupColor = color
9596
}
9697

98+
//GenCaptchaImage 生成文字的验证码图片
9799
func (cp *Captcha) GenCaptchaImage(text string) (CaptchaResult, error) {
98100

99101
result := CaptchaResult{}
@@ -126,11 +128,65 @@ func (cp *Captcha) GenCaptchaImage(text string) (CaptchaResult, error) {
126128
result.ImageBase64 = fmt.Sprintf("data:%s;base64,%s", "image/png", base64.StdEncoding.EncodeToString(imageBytes))
127129
result.Text = text
128130

129-
// writeImageFile("./test.png", imageBytes)
131+
// writeImageFile("./previews/test.png", imageBytes)
130132
return result, nil
131133

132134
}
133135

136+
//GenNormalRandomCaptcha 随机验证码 - 普通验证码
137+
func (cp *Captcha) GenRandomNormalCaptcha(length int) (CaptchaResult, error) {
138+
var buff bytes.Buffer
139+
140+
for i := 0; i < length; i++ {
141+
ix := rand.Intn(length)
142+
buff.WriteByte(Alphabets[ix])
143+
}
144+
145+
return cp.GenCaptchaImage(buff.String())
146+
147+
}
148+
149+
//GenBehaviorCaptcha 生成中文点击验证码 - 点击行为验证码
150+
func (cp *Captcha) GenBehaviorCaptcha() (CaptchaResult, error) {
151+
152+
ix := rand.Intn(len(CNChars))
153+
return cp.GenCaptchaImage(CNChars[ix])
154+
155+
}
156+
157+
//ValidBehaviorCaptcha 验证行为点击验证码是否正确
158+
func ValidBehaviorCaptcha(cr CaptchaResult, userPoints []Point) bool {
159+
//字符数量不相等
160+
return ValidBehaviorRects(cr.DrawRects, userPoints)
161+
}
162+
163+
//ValidBehaviorRects 验证行为点是否在验证码矩形中
164+
func ValidBehaviorRects(rects []DrawRect, userPoints []Point) bool {
165+
166+
if len(userPoints) != len(rects) {
167+
return false
168+
}
169+
170+
for i := 0; i < len(userPoints); i++ {
171+
realRect := rects[i]
172+
userPos := userPoints[i]
173+
174+
if !PointInRect(userPos, realRect) {
175+
return false
176+
}
177+
}
178+
return true
179+
180+
}
181+
182+
//PointInRect 验证点是否在矩形中
183+
func PointInRect(p Point, rect DrawRect) bool {
184+
if p.X >= rect.X && p.X <= rect.X+rect.Width && p.Y >= rect.Y && p.Y <= rect.Y+rect.Height {
185+
return true
186+
}
187+
return false
188+
}
189+
134190
func encodingWithPng(img image.Image) (encodeResult []byte, err error) {
135191

136192
var buf bytes.Buffer
@@ -146,6 +202,7 @@ func encodingWithPng(img image.Image) (encodeResult []byte, err error) {
146202

147203
}
148204

205+
//writeImageFile tmp
149206
func writeImageFile(filepath string, imageBytes []byte) {
150207
file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE, 0666)
151208
if err != nil {

‎captcha_test.go

+101-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,108 @@ import (
88
func TestGenCaptcha(t *testing.T) {
99

1010
cpt := NewCaptcha(260, 100)
11-
cpt.SetBackgroundColor(color.RGBA{R: uint8(20), G: uint8(8), B: uint8(100), A: uint8(255)})
11+
// cpt.SetBackgroundColor(color.RGBA{R: uint8(20), G: uint8(8), B: uint8(100), A: uint8(255)})
1212
// cpt.Config.Style = CaptchaStyle_Behavior
1313
result, err := cpt.GenCaptchaImage("3567")
1414
t.Logf("GenCaptchaImage: %+v %+v", result, err)
1515
}
16+
17+
func TestGenNormalCaptcha(t *testing.T) {
18+
19+
cpt := NewCaptcha(260, 100)
20+
cpt.SetBackgroundColor(color.RGBA{R: uint8(20), G: uint8(8), B: uint8(100), A: uint8(255)})
21+
// cpt.Config.Style = CaptchaStyle_Behavior
22+
result, err := cpt.GenRandomNormalCaptcha(4)
23+
t.Logf("GenCaptchaImage: %+v %+v", result, err)
24+
}
25+
26+
func TestGenGenBehaviorCaptcha(t *testing.T) {
27+
28+
cpt := NewCaptcha(260, 100)
29+
cpt.SetBackgroundColor(color.RGBA{R: uint8(20), G: uint8(8), B: uint8(100), A: uint8(255)})
30+
// cpt.Config.Style = CaptchaStyle_Behavior
31+
cpt.Config.MaxRotate = 20
32+
result, err := cpt.GenBehaviorCaptcha()
33+
t.Logf("GenCaptchaImage: %+v %+v", result, err)
34+
}
35+
36+
func TestPointInRect(t *testing.T) {
37+
rect := DrawRect{X: 10, Width: 50, Y: 50, Height: 60}
38+
point := Point{X: 10, Y: 40}
39+
40+
if PointInRect(point, rect) {
41+
t.Errorf("PointInRect error")
42+
}
43+
44+
point = Point{X: 10, Y: 50}
45+
if !PointInRect(point, rect) {
46+
t.Errorf("PointInRect error")
47+
}
48+
49+
point = Point{X: 10, Y: 60}
50+
if !PointInRect(point, rect) {
51+
t.Errorf("PointInRect error")
52+
}
53+
54+
point = Point{X: 10, Y: 110}
55+
if !PointInRect(point, rect) {
56+
t.Errorf("PointInRect error")
57+
}
58+
59+
point = Point{X: 30, Y: 110}
60+
if !PointInRect(point, rect) {
61+
t.Errorf("PointInRect error")
62+
}
63+
64+
point = Point{X: 60, Y: 110}
65+
if !PointInRect(point, rect) {
66+
t.Errorf("PointInRect error")
67+
}
68+
}
69+
70+
func TestValidBehaviorCaptcha(t *testing.T) {
71+
cr := CaptchaResult{}
72+
cr.DrawRects = []DrawRect{
73+
DrawRect{X: 10, Y: 10, Width: 60, Height: 60},
74+
DrawRect{X: 20, Y: 60, Width: 60, Height: 60},
75+
DrawRect{X: 60, Y: 90, Width: 60, Height: 60},
76+
}
77+
78+
ps := []Point{
79+
Point{X: 15, Y: 8},
80+
}
81+
82+
if ValidBehaviorCaptcha(cr, ps) {
83+
t.Errorf("invalid error")
84+
}
85+
if !ValidBehaviorCaptcha(cr, ps) {
86+
t.Logf("invalid captcha")
87+
}
88+
89+
ps = []Point{
90+
Point{X: 15, Y: 8},
91+
Point{X: 15, Y: 8},
92+
Point{X: 15, Y: 8},
93+
}
94+
if ValidBehaviorCaptcha(cr, ps) {
95+
t.Errorf("invalid error")
96+
}
97+
98+
ps = []Point{
99+
Point{X: 15, Y: 12},
100+
Point{X: 20, Y: 62},
101+
Point{X: 60, Y: 8},
102+
}
103+
if ValidBehaviorCaptcha(cr, ps) {
104+
t.Errorf("invalid error")
105+
}
106+
107+
ps = []Point{
108+
Point{X: 15, Y: 12},
109+
Point{X: 20, Y: 62},
110+
Point{X: 60, Y: 98},
111+
}
112+
if ValidBehaviorCaptcha(cr, ps) {
113+
t.Logf("valid captcha")
114+
}
115+
}

‎previews/test_1.png

3.93 KB
Loading

‎previews/test_2.png

4.41 KB
Loading

0 commit comments

Comments
 (0)
Please sign in to comment.