-
Notifications
You must be signed in to change notification settings - Fork 274
/
driver_digit.go
88 lines (79 loc) · 2.92 KB
/
driver_digit.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
// Copyright 2017 Eric Zhou. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package base64Captcha
import "math/rand"
// DriverDigit config for captcha-engine-digit.
type DriverDigit struct {
// Height png height in pixel.
Height int
// Width Captcha png width in pixel.
Width int
// DefaultLen Default number of digits in captcha solution.
Length int
// MaxSkew max absolute skew factor of a single digit.
MaxSkew float64
// DotCount Number of background circles.
DotCount int
}
// NewDriverDigit creates a driver of digit
func NewDriverDigit(height int, width int, length int, maxSkew float64, dotCount int) *DriverDigit {
return &DriverDigit{Height: height, Width: width, Length: length, MaxSkew: maxSkew, DotCount: dotCount}
}
// DefaultDriverDigit is a default driver of digit
var DefaultDriverDigit = NewDriverDigit(80, 240, 5, 0.7, 80)
// GenerateIdQuestionAnswer creates captcha content and answer
func (d *DriverDigit) GenerateIdQuestionAnswer() (id, q, a string) {
id = RandomId()
digits := randomDigits(d.Length)
a = parseDigitsToString(digits)
return id, a, a
}
// GenerateIdQuestionAnswer creates captcha content and answer
func (d *DriverDigit) GenerateSpecificIdQuestionAnswer(mId string) (id, q, a string) {
id = mId
digits := randomDigits(d.Length)
a = parseDigitsToString(digits)
return id, a, a
}
// DrawCaptcha creates digit captcha item
func (d *DriverDigit) DrawCaptcha(content string) (item Item, err error) {
// Initialize PRNG.
itemDigit := NewItemDigit(d.Width, d.Height, d.DotCount, d.MaxSkew)
//parse digits to string
digits := stringToFakeByte(content)
itemDigit.calculateSizes(d.Width, d.Height, len(digits))
// Randomly position captcha inside the image.
maxx := d.Width - (itemDigit.width+itemDigit.dotSize)*len(digits) - itemDigit.dotSize
maxy := d.Height - itemDigit.height - itemDigit.dotSize*2
var border int
if d.Width > d.Height {
border = d.Height / 5
} else {
border = d.Width / 5
}
x := rand.Intn(maxx-border*2) + border
y := rand.Intn(maxy-border*2) + border
// Draw digits.
for _, n := range digits {
itemDigit.drawDigit(digitFontData[n], x, y)
x += itemDigit.width + itemDigit.dotSize
}
// Draw strike-through line.
itemDigit.strikeThrough()
// Apply wave distortion.
itemDigit.distort(rand.Float64()*(10-5)+5, rand.Float64()*(200-100)+100)
// Fill image with random circles.
itemDigit.fillWithCircles(d.DotCount, itemDigit.dotSize)
return itemDigit, nil
}