.
このコミットが含まれているのは:
コミット
366283bd62
7
go.mod
7
go.mod
|
@ -2,7 +2,6 @@ module gitler.moe/suwako/gocaptcha
|
||||||
|
|
||||||
go 1.21.1
|
go 1.21.1
|
||||||
|
|
||||||
require (
|
require golang.org/x/image v0.12.0
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
|
||||||
golang.org/x/image v0.12.0
|
require golang.org/x/text v0.13.0 // indirect
|
||||||
)
|
|
||||||
|
|
3
go.sum
3
go.sum
|
@ -1,5 +1,3 @@
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
@ -27,6 +25,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
|
33
main.go
33
main.go
|
@ -1,7 +1,6 @@
|
||||||
package gocaptcha
|
package gocaptcha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"image"
|
"image"
|
||||||
|
@ -11,10 +10,12 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
"bytes"
|
||||||
|
|
||||||
"golang.org/x/image/font"
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/font/sfnt"
|
||||||
"golang.org/x/image/math/fixed"
|
"golang.org/x/image/math/fixed"
|
||||||
"github.com/golang/freetype/truetype"
|
"golang.org/x/image/font/opentype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Captcha struct {
|
type Captcha struct {
|
||||||
|
@ -38,23 +39,29 @@ func GenerateCaptcha(fontPath, charset string, length int) (*Captcha, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := truetype.Parse(fontBytes)
|
f, err := sfnt.Parse(fontBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
face, err := opentype.NewFace(f, &opentype.FaceOptions{
|
||||||
|
Size: 24,
|
||||||
|
DPI: 72,
|
||||||
|
Hinting: font.HintingFull,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer face.Close()
|
||||||
|
|
||||||
img := image.NewRGBA(image.Rect(0, 0, 300, 100))
|
img := image.NewRGBA(image.Rect(0, 0, 300, 100))
|
||||||
bgColor := color.RGBA{0, 0, 0, 255}
|
bgColor := color.RGBA{0, 0, 0, 255}
|
||||||
draw.Draw(img, img.Bounds(), &image.Uniform{bgColor}, image.Point{}, draw.Src)
|
draw.Draw(img, img.Bounds(), &image.Uniform{bgColor}, image.Point{}, draw.Src)
|
||||||
|
|
||||||
d := &font.Drawer{
|
d := &font.Drawer{
|
||||||
Dst: img,
|
Dst: img,
|
||||||
Src: image.NewUniform(color.RGBA{255, 255, 255, 255}),
|
Src: image.NewUniform(color.RGBA{255, 255, 255, 255}),
|
||||||
Face: truetype.NewFace(f, &truetype.Options{
|
Face: face,
|
||||||
Size: 24,
|
|
||||||
DPI: 72,
|
|
||||||
Hinting: font.HintingFull,
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Dot = fixed.Point26_6{
|
d.Dot = fixed.Point26_6{
|
||||||
|
@ -83,12 +90,10 @@ func VerifyCaptcha(input, captchaText string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func genTxt(charset string, length int) string {
|
func genTxt(charset string, length int) string {
|
||||||
runes := []rune(charset)
|
|
||||||
text := make([]rune, length)
|
text := make([]rune, length)
|
||||||
for i := range text {
|
for i := range text {
|
||||||
bigIndex, _ := rand.Int(rand.Reader, big.NewInt(int64(len(runes))))
|
randomIndex, _ := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
|
||||||
randomIndex := int(bigIndex.Int64())
|
text[i] = rune(charset[randomIndex.Int64()])
|
||||||
text[i] = runes[randomIndex]
|
|
||||||
}
|
}
|
||||||
return string(text)
|
return string(text)
|
||||||
}
|
}
|
||||||
|
|
読み込み中…
新しいイシューから参照