Compare commits

..

No commits in common. "main" and "v1.4.1" have entirely different histories.
main ... v1.4.1

8 changed files with 56 additions and 68 deletions

24
.github/workflows/go.yml vendored Normal file
View file

@ -0,0 +1,24 @@
name: CI
on: [push, pull_request]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Golang
uses: actions/setup-go@v2
with:
go-version: '^1.16.0'
- run: go version
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: install dependencies
run: go mod download
- name: run test
run: go test -race -coverprofile=coverage.txt -covermode=atomic
- name: upload coverage
run: bash <(curl -s https://codecov.io/bash)

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2017 - 2024 Weilin Shi Copyright (c) 2017 - 2021 Weilin Shi
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -2,17 +2,19 @@
<div> <div>
[![PkgGoDev](https://pkg.go.dev/badge/concord.hectabit.org/HectaBit/captcha)](https://pkg.go.dev/concord.hectabit.org/HectaBit/captcha) [![PkgGoDev](https://pkg.go.dev/badge/github.com/steambap/captcha)](https://pkg.go.dev/github.com/steambap/captcha)
[![Go Report Card](https://goreportcard.com/badge/concord.hectabit.org/HectaBit/captcha)](https://goreportcard.com/report/concord.hectabit.org/HectaBit/captcha) [![Build Status](https://github.com/steambap/captcha/workflows/CI/badge.svg)](https://github.com/steambap/captcha/actions?workflow=CI)
[![codecov](https://codecov.io/gh/steambap/captcha/branch/main/graph/badge.svg)](https://codecov.io/gh/steambap/captcha)
[![Go Report Card](https://goreportcard.com/badge/github.com/steambap/captcha)](https://goreportcard.com/report/github.com/steambap/captcha)
</div> </div>
## Why another captcha generator? ## Why another captcha generator?
Because I can. I want a simple and framework-independent way to generate captcha. It also should be flexible, at least allow me to pick my favorite font.
## install ## install
``` ```
go get concord.hectabit.org/HectaBit/captcha go get github.com/steambap/captcha
``` ```
## usage ## usage
@ -30,9 +32,8 @@ func handle(w http.ResponseWriter, r *http.Request) {
``` ```
[documentation](https://pkg.go.dev/concord.hectabit.org/HectaBit/captcha) | [documentation](https://pkg.go.dev/github.com/steambap/captcha) |
[example](example/basic/main.go) | [example](example/basic/main.go)
[font example](example/load-font/main.go)
## sample image ## sample image
![image](example/captcha.png) ![image](example/captcha.png)

View file

@ -62,7 +62,7 @@ func newDefaultOption(width, height int) *Options {
return &Options{ return &Options{
BackgroundColor: color.Transparent, BackgroundColor: color.Transparent,
CharPreset: charPreset, CharPreset: charPreset,
TextLength: 6, TextLength: 4,
CurveNumber: 2, CurveNumber: 2,
FontDPI: 72.0, FontDPI: 72.0,
FontScale: 1.0, FontScale: 1.0,
@ -136,7 +136,11 @@ func New(width int, height int, option ...SetOption) (*Data, error) {
text := randomText(options) text := randomText(options)
img := image.NewNRGBA(image.Rect(0, 0, width, height)) img := image.NewNRGBA(image.Rect(0, 0, width, height))
if err := drawWithOption(text, img, options); err != nil { draw.Draw(img, img.Bounds(), &image.Uniform{options.BackgroundColor}, image.Point{}, draw.Src)
drawNoise(img, options)
drawCurves(img, options)
err := drawText(text, img, options)
if err != nil {
return nil, err return nil, err
} }
@ -153,42 +157,21 @@ func NewMathExpr(width int, height int, option ...SetOption) (*Data, error) {
text, equation := randomEquation() text, equation := randomEquation()
img := image.NewNRGBA(image.Rect(0, 0, width, height)) img := image.NewNRGBA(image.Rect(0, 0, width, height))
if err := drawWithOption(equation, img, options); err != nil { draw.Draw(img, img.Bounds(), &image.Uniform{options.BackgroundColor}, image.Point{}, draw.Src)
drawNoise(img, options)
drawCurves(img, options)
err := drawText(equation, img, options)
if err != nil {
return nil, err return nil, err
} }
return &Data{Text: text, img: img}, nil return &Data{Text: text, img: img}, nil
} }
// NewCustomGenerator creates a new captcha based on a custom text generator.
func NewCustomGenerator(
width int, height int, generator func() (anwser string, question string), option ...SetOption,
) (*Data, error) {
options := newDefaultOption(width, height)
for _, setOption := range option {
setOption(options)
}
answer, question := generator()
img := image.NewNRGBA(image.Rect(0, 0, width, height))
if err := drawWithOption(question, img, options); err != nil {
return nil, err
}
return &Data{Text: answer, img: img}, nil
}
func drawWithOption(text string, img *image.NRGBA, options *Options) error {
draw.Draw(img, img.Bounds(), &image.Uniform{options.BackgroundColor}, image.Point{}, draw.Src)
drawNoise(img, options)
drawCurves(img, options)
return drawText(text, img, options)
}
func randomText(opts *Options) (text string) { func randomText(opts *Options) (text string) {
n := len([]rune(opts.CharPreset)) n := len(opts.CharPreset)
for i := 0; i < opts.TextLength; i++ { for i := 0; i < opts.TextLength; i++ {
text += string([]rune(opts.CharPreset)[rand.Intn(n)]) text += string(opts.CharPreset[rand.Intn(n)])
} }
return text return text

View file

@ -69,12 +69,6 @@ func TestNewCaptchaOptions(t *testing.T) {
NewMathExpr(100, 34, func(options *Options) { NewMathExpr(100, 34, func(options *Options) {
options.BackgroundColor = color.Black options.BackgroundColor = color.Black
}) })
NewCustomGenerator(100, 34, func() (anwser string, question string) {
return "4", "2x2?"
}, func(o *Options) {
o.BackgroundColor = color.Black
})
} }
func TestNewMathExpr(t *testing.T) { func TestNewMathExpr(t *testing.T) {
@ -84,15 +78,6 @@ func TestNewMathExpr(t *testing.T) {
} }
} }
func TestNewCustomGenerator(t *testing.T) {
_, err := NewCustomGenerator(150, 50, func() (anwser string, question string) {
return "1", "2"
})
if err != nil {
t.Fatal(err)
}
}
func TestNilFontError(t *testing.T) { func TestNilFontError(t *testing.T) {
temp := ttfFont temp := ttfFont
ttfFont = nil ttfFont = nil
@ -107,13 +92,6 @@ func TestNilFontError(t *testing.T) {
t.Fatal("Expect to get nil font error") t.Fatal("Expect to get nil font error")
} }
_, err = NewCustomGenerator(150, 50, func() (anwser string, question string) {
return "1", "2"
})
if err == nil {
t.Fatal("Expect to get nil font error")
}
ttfFont = temp ttfFont = temp
} }

View file

@ -1,7 +1,7 @@
module concord.hectabit.org/HectaBit/captcha/example/basic module github.com/steambap/captcha/example/basic
go 1.12 go 1.12
replace concord.hectabit.org/HectaBit/captcha => ../../ replace github.com/steambap/captcha => ../../
require concord.hectabit.org/HectaBit/captcha v0.0.0-00010101000000-000000000000 require github.com/steambap/captcha v0.0.0-00010101000000-000000000000

6
go.mod
View file

@ -1,8 +1,8 @@
module concord.hectabit.org/HectaBit/captcha module github.com/steambap/captcha
go 1.20 go 1.16
require ( require (
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
golang.org/x/image v0.15.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
) )

6
go.sum
View file

@ -1,4 +1,6 @@
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= 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/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=