Compare commits

...

28 commits
v1.3.1 ... main

Author SHA1 Message Date
669a328c35 Moved to concord 2024-07-10 16:49:19 +01:00
31a767886d Update captcha.go 2024-05-02 00:29:35 +01:00
8b04542f19 Update README.md 2024-05-02 00:25:23 +01:00
0d18ee4d3f Update README.md 2024-05-02 00:24:46 +01:00
98c666bea2 Delete .github/workflows/go.yml 2024-05-02 00:23:57 +01:00
d294d79360 Update example/basic/go.mod 2024-05-02 00:23:41 +01:00
b4b097a927 Update go.mod 2024-05-02 00:22:56 +01:00
Weilin Shi
c34288c982 update deps 2024-01-13 09:53:15 +08:00
Weilin Shi
2f847d5947 upgrade x/image 2023-07-26 14:04:50 +08:00
dependabot[bot]
fef853ee5e
build(deps): bump golang.org/x/image from 0.1.0 to 0.5.0 (#10)
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.1.0 to 0.5.0.
- [Release notes](https://github.com/golang/image/releases)
- [Commits](https://github.com/golang/image/compare/v0.1.0...v0.5.0)

---
updated-dependencies:
- dependency-name: golang.org/x/image
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-09 17:02:21 +08:00
Zhiger
1d4172a01f
fix: wrong randomText when unicode preset (#8) 2023-02-16 21:06:39 +08:00
Weilin Shi
6b08f978b6 update go.mod and license 2023-01-01 08:34:24 +08:00
Weilin Shi
9234bd71dd update deps 2022-12-05 16:17:24 +08:00
Weilin Shi
f6fd454518 fix #7 2022-06-27 13:00:35 +08:00
Weilin Shi
20014aab1b new custom generator api 2022-06-10 12:16:34 +08:00
Weilin Shi
6aa88d953f test go 1.18 2022-03-22 15:23:39 +08:00
Weilin Shi
019b34f8f2 update deps and license 2022-01-06 20:44:35 +08:00
Weilin Shi
80cb7ffd68 update readme 2021-09-28 16:44:12 +08:00
Weilin Shi
02532e6f4d fix old code style 2021-08-25 15:21:16 +08:00
Weilin Shi
ba2a083ab6 update code of conduct 2021-08-24 21:15:10 +08:00
Weilin Shi
a4223da22a fix typo and lint 2021-07-28 21:26:53 +08:00
Weilin Shi
53e75b199a upgrade to use embed from Go 1.16 2021-07-28 21:22:23 +08:00
Weilin Shi
cccc7a97ea remove used section in readme 2021-06-22 14:14:22 +08:00
Weilin Shi
87b02acaf1 update compatibility notes 2021-06-22 14:13:41 +08:00
Weilin Shi
ba5dfca752 go mod tidy 2021-06-15 21:23:55 +08:00
Weilin Shi
1bc08e3651 happy new year 2021-01-01 09:50:41 +08:00
Weilin Shi
3915a04f79 go tide module 2020-10-13 16:39:37 +08:00
Weilin Shi
b69ec48f20 fix pkg go dev link 2020-09-22 11:04:26 +08:00
11 changed files with 79 additions and 5142 deletions

View file

@ -1,24 +0,0 @@
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.13.1'
- 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
Copyright (c) 2017 - 2020 Weilin Shi
Copyright (c) 2017 - 2024 Weilin Shi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -2,19 +2,17 @@
<div>
[![PkgGoDev](https://pkg.go.dev/badge/steambap/captcha)](https://pkg.go.dev/steambap/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)
[![PkgGoDev](https://pkg.go.dev/badge/concord.hectabit.org/HectaBit/captcha)](https://pkg.go.dev/concord.hectabit.org/HectaBit/captcha)
[![Go Report Card](https://goreportcard.com/badge/concord.hectabit.org/HectaBit/captcha)](https://goreportcard.com/report/concord.hectabit.org/HectaBit/captcha)
</div>
## Why another captcha generator?
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.
Because I can.
## install
```
go get github.com/steambap/captcha
go get concord.hectabit.org/HectaBit/captcha
```
## usage
@ -32,14 +30,19 @@ func handle(w http.ResponseWriter, r *http.Request) {
```
[documentation](https://godoc.org/github.com/steambap/captcha) |
[example](example/basic/main.go)
[documentation](https://pkg.go.dev/concord.hectabit.org/HectaBit/captcha) |
[example](example/basic/main.go) |
[font example](example/load-font/main.go)
## sample image
![image](example/captcha.png)
![image](example/captcha-math.png)
## Compatibility
This package uses embed package from Go 1.16. If for some reasons you have to use pre 1.16 version of Go, reference pre 1.4 version of this module in your go.mod.
## Contributing
If your found a bug, please contribute!
see [contributing.md](contributing.md) for more detail.

View file

@ -2,7 +2,7 @@
package captcha
import (
"bytes"
_ "embed" // embed font
"image"
"image/color"
"image/draw"
@ -22,6 +22,8 @@ import (
const charPreset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
//go:embed fonts/Comismsh.ttf
var ttf []byte
var ttfFont *truetype.Font
// Options manage captcha generation details.
@ -60,7 +62,7 @@ func newDefaultOption(width, height int) *Options {
return &Options{
BackgroundColor: color.Transparent,
CharPreset: charPreset,
TextLength: 4,
TextLength: 6,
CurveNumber: 2,
FontDPI: 72.0,
FontScale: 1.0,
@ -116,12 +118,12 @@ func LoadFont(fontData []byte) error {
// LoadFontFromReader load an external font from an io.Reader interface.
func LoadFontFromReader(reader io.Reader) error {
var buf bytes.Buffer
if _, err := io.Copy(&buf, reader); err != nil {
b, err := io.ReadAll(reader)
if err != nil {
return err
}
return LoadFont(buf.Bytes())
return LoadFont(b)
}
// New creates a new captcha.
@ -134,11 +136,7 @@ func New(width int, height int, option ...SetOption) (*Data, error) {
text := randomText(options)
img := image.NewNRGBA(image.Rect(0, 0, width, height))
draw.Draw(img, img.Bounds(), &image.Uniform{options.BackgroundColor}, image.ZP, draw.Src)
drawNoise(img, options)
drawCurves(img, options)
err := drawText(text, img, options)
if err != nil {
if err := drawWithOption(text, img, options); err != nil {
return nil, err
}
@ -155,21 +153,42 @@ func NewMathExpr(width int, height int, option ...SetOption) (*Data, error) {
text, equation := randomEquation()
img := image.NewNRGBA(image.Rect(0, 0, width, height))
draw.Draw(img, img.Bounds(), &image.Uniform{options.BackgroundColor}, image.ZP, draw.Src)
drawNoise(img, options)
drawCurves(img, options)
err := drawText(equation, img, options)
if err != nil {
if err := drawWithOption(equation, img, options); err != nil {
return nil, err
}
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) {
n := len(opts.CharPreset)
n := len([]rune(opts.CharPreset))
for i := 0; i < opts.TextLength; i++ {
text += string(opts.CharPreset[rand.Intn(n)])
text += string([]rune(opts.CharPreset)[rand.Intn(n)])
}
return text

View file

@ -69,6 +69,12 @@ func TestNewCaptchaOptions(t *testing.T) {
NewMathExpr(100, 34, func(options *Options) {
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) {
@ -78,6 +84,15 @@ 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) {
temp := ttfFont
ttfFont = nil
@ -92,6 +107,13 @@ func TestNilFontError(t *testing.T) {
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
}

View file

@ -1 +1 @@
[https://contributor-covenant.org/version/1/4/](https://contributor-covenant.org/version/1/4/)
[https://www.contributor-covenant.org/version/2/1/code_of_conduct/](https://www.contributor-covenant.org/version/2/1/code_of_conduct/)

View file

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

5016
font.go

File diff suppressed because it is too large Load diff

View file

@ -1,40 +0,0 @@
package main
import (
"bytes"
"fmt"
"go/format"
"io/ioutil"
"log"
"path/filepath"
)
// This program generates a go file for Comismsh font
func main() {
src, err := ioutil.ReadFile("Comismsh.ttf")
if err != nil {
log.Fatal(err)
}
buf := new(bytes.Buffer)
fmt.Fprint(buf, "// DO NOT EDIT. This file is generated.\n\n")
fmt.Fprint(buf, "package captcha\n\n")
fmt.Fprint(buf, "// The following is Comismsh TrueType font data.\n")
fmt.Fprint(buf, "var ttf = []byte{")
for i, x := range src {
if i&15 == 0 {
buf.WriteByte('\n')
}
fmt.Fprintf(buf, "%#02x,", x)
}
fmt.Fprint(buf, "\n}\n")
dst, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join("../", "font.go"), dst, 0666); err != nil {
log.Fatal(err)
}
}

13
go.mod
View file

@ -1,15 +1,8 @@
module github.com/steambap/captcha
module concord.hectabit.org/HectaBit/captcha
go 1.12
go 1.20
require (
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f // indirect
golang.org/x/image v0.0.0-20200618115811-c13761719519
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 // indirect
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98 // indirect
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect
golang.org/x/image v0.15.0
)

24
go.sum
View file

@ -1,24 +1,4 @@
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=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/image v0.0.0-20190507092727-e4e5bf290fec h1:arXJwtMuk5vqI1NHX0UTnNw977rYk5Sl4jQqHj+hun4=
golang.org/x/image v0.0.0-20190507092727-e4e5bf290fec/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34=
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=