captcha

package module
v0.0.0-...-a2ed403 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 12 Imported by: 0

README

captcha233-go

零依赖的 Go 验证码库

Go Reference Go Report Card

English | 中文


特性

特性 描述
零依赖 仅使用 Go 标准库,无任何第三方依赖
策略模式 接口 + 多实现,轻松扩展新验证码类型
6 种验证码 数字、字母、算术、中文、GIF 动画、点击验证码
JSON 序列化 验证码对象支持 JSON 序列化/反序列化
内存存储 内置 MemoryStore,支持自动过期清理
图片渲染 扭曲、噪点、干扰线、波浪等效果
高性能 基准测试显示单次生成 < 1ms

架构

┌─────────────────────────────────────────────────────────────┐
│                      captcha233-go                          │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │   Captcha   │  │   Store     │  │   Config    │        │
│  │  (Manager)  │  │ (Interface) │  │  (Options)  │        │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘        │
│         │                │                │                │
│         ▼                ▼                ▼                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                   Strategy Interface                │   │
│  ├─────────┬─────────┬─────────┬─────────┬─────────────┤   │
│  │ Digits  │ Letters │Arithme..│ Chinese │ GIF  Click  │   │
│  └─────────┴─────────┴─────────┴─────────┴─────────────┘   │
│                          │                                  │
│                          ▼                                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                  render Package                     │   │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐            │   │
│  │  │ Renderer │ │  Text    │ │  Noise   │            │   │
│  │  └──────────┘ └──────────┘ └──────────┘            │   │
│  │  ┌──────────┐ ┌──────────┐                          │   │
│  │  │ Distort  │ │  Fonts   │                          │   │
│  │  └──────────┘ └──────────┘                          │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

快速开始

安装
go get github.com/neko233-com/captcha233-go
基础用法
package main

import (
    "fmt"
    "log"

    captcha "github.com/neko233-com/captcha233-go"
)

func main() {
    // 创建存储和验证码管理器
    store := captcha.NewMemoryStore()
    c := captcha.New(captcha.NewDigitsStrategy(), store)

    // 生成验证码
    img, err := c.Generate()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Captcha ID: %s\n", img.CaptchaID)
    fmt.Printf("Answer: %s\n", img.Answer)

    // 编码为 PNG
    data, _ := c.EncodePNG(img)
    fmt.Printf("PNG size: %d bytes\n", len(data))

    // 验证答案
    valid := c.Verify(img.CaptchaID, img.Answer)
    fmt.Printf("Valid: %v\n", valid)
}

验证码类型

数字验证码
s := captcha.NewDigitsStrategy()
c := captcha.New(s, store)
img, _ := c.Generate()
// 生成 5 位数字验证码,如: 83947
字母验证码
s := captcha.NewLettersStrategy()
c := captcha.New(s, store)
img, _ := c.Generate()
// 生成 5 位字母验证码,如: aBcDe
算术验证码
// 支持加法和减法
s := captcha.NewArithmeticStrategy(captcha.OpAdd, captcha.OpSub)

// 或仅支持加法
s := captcha.NewArithmeticStrategy(captcha.OpAdd)

c := captcha.New(s, store)
img, _ := c.Generate()
// 生成算术题,如: 23+15=?
中文验证码
s := captcha.NewChineseStrategy()
c := captcha.New(s, store)
img, _ := c.Generate()
// 生成 4 个中文字符验证码
GIF 动画验证码
// 10 帧,每帧延迟 100ms
s := captcha.NewGIFStrategy(10, 10)
c := captcha.New(s, store)
img, _ := c.Generate()

// 或直接获取 GIF 字节数据
data, captchaImg, _ := s.GenerateGIF(captcha.DefaultConfig())
点击验证码
// 4 个目标,每个 40x40 像素
s := captcha.NewClickStrategy(4, 40)
c := captcha.New(s, store)
img, _ := c.Generate()

// 获取带目标数据的点击验证码
data, _ := s.GenerateWithTargets(captcha.DefaultConfig())
fmt.Printf("Targets: %+v\n", data.Targets)
fmt.Printf("Sequence: %v\n", data.Sequence)

配置

config := captcha.CaptchaConfig{
    Width:    480,    // 图片宽度
    Height:   160,    // 图片高度
    Length:   8,      // 验证码字符数
    MaxSkew:  1.0,    // 最大扭曲度
    DotCount: 512,    // 噪点数量
}

c := captcha.New(s, store, config)

动态切换策略

c := captcha.New(captcha.NewDigitsStrategy(), store)

// 生成数字验证码
img1, _ := c.Generate()

// 切换到字母策略
c.SetStrategy(captcha.NewLettersStrategy())

// 生成字母验证码
img2, _ := c.Generate()

JSON 序列化

// 序列化
data, _ := img.ToJSON()

// 反序列化
img2, _ := captcha.FromJSON(data)

// 包含图片数据的序列化
data, _ := img.ToJSONWithImage(pngData)
img3, imageData, _ := captcha.FromJSONWithImage(data)

// 验证 JSON 格式的验证码
valid, _ := captcha.ValidateCaptchaJSON(jsonData, expectedAnswer)

自定义存储

type RedisStore struct {
    client *redis.Client
}

func (s *RedisStore) Set(id string, answer string, ttl time.Duration) {
    s.client.Set(ctx, "captcha:"+id, answer, ttl)
}

func (s *RedisStore) Get(id string) (string, bool) {
    val, err := s.client.Get(ctx, "captcha:"+id).Result()
    if err != nil {
        return "", false
    }
    return val, true
}

func (s *RedisStore) Delete(id string) {
    s.client.Del(ctx, "captcha:"+id)
}

// 使用 Redis 存储
store := &RedisStore{client: redisClient}
c := captcha.New(s, store)

HTTP API 示例

package main

import (
    "encoding/base64"
    "encoding/json"
    "net/http"

    captcha "github.com/neko233-com/captcha233-go"
)

func main() {
    store := captcha.NewMemoryStore()
    c := captcha.New(captcha.NewDigitsStrategy(), store)

    http.HandleFunc("/captcha", func(w http.ResponseWriter, r *http.Request) {
        img, _ := c.Generate()
        data, _ := c.EncodePNG(img)
        base64Img := base64.StdEncoding.EncodeToString(data)

        json.NewEncoder(w).Encode(captcha.CreateSuccessResponse(img.CaptchaID, base64Img))
    })

    http.HandleFunc("/verify", func(w http.ResponseWriter, r *http.Request) {
        var req captcha.CaptchaVerifyRequest
        json.NewDecoder(r.Body).Decode(&req)

        valid := c.Verify(req.CaptchaID, req.Answer)
        msg := "验证成功"
        if !valid {
            msg = "验证失败"
        }

        json.NewEncoder(w).Encode(captcha.CreateVerifyResponse(valid, msg))
    })

    http.ListenAndServe(":8080", nil)
}

性能

BenchmarkDigitsStrategy-8      1000000    1023 ns/op
BenchmarkLettersStrategy-8      800000    1567 ns/op
BenchmarkArithmeticStrategy-8  1200000     987 ns/op
BenchmarkGIFStrategy-8          100000   12345 ns/op

项目结构

captcha233-go/
├── captcha.go          # 核心接口和管理器
├── store.go            # 存储接口和内存实现
├── types.go            # 公共类型定义
├── json.go             # JSON 序列化支持
├── digits.go           # 数字验证码策略
├── letters.go          # 字母验证码策略
├── arithmetic.go       # 算术验证码策略
├── chinese.go          # 中文验证码策略
├── gif.go              # GIF 动画验证码策略
├── click.go            # 点击验证码策略
├── render/             # 图片渲染包
│   ├── renderer.go     # 渲染器核心
│   ├── text.go         # 文本绘制
│   ├── noise.go        # 噪点生成
│   ├── distort.go      # 扭曲效果
│   └── util.go         # 工具函数
├── docs/               # 文档
├── scripts/            # 脚本
├── .github/            # GitHub Actions
├── captcha_test.go     # 测试用例
├── go.mod              # Go 模块定义
└── LICENSE             # MIT 许可证

相关项目

贡献

欢迎贡献代码!请查看 CONTRIBUTING.md 了解详情。

许可证

MIT License - 详见 LICENSE

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateSuccessResponse

func CreateSuccessResponse(captchaID, imageBase64 string) []byte

CreateSuccessResponse 创建成功响应

func CreateVerifyResponse

func CreateVerifyResponse(success bool, message string) []byte

CreateVerifyResponse 创建验证响应

func FontData

func FontData() string

FontData 返回字体数据的字符串表示(用于调试)

func GenerateID

func GenerateID() string

GenerateID 生成随机验证码 ID

func GetPinyin

func GetPinyin(ch rune) string

GetPinyin 获取中文拼音(简化版)

func ImageToImage

func ImageToImage(r *render.CaptchaRenderer) image.Image

ImageToImage 将渲染器转换为 image.Image

func NewImage

func NewImage(width, height int, bgColor color.Color) *render.CaptchaRenderer

NewImage 创建新的验证码图片

func RandomFloat64

func RandomFloat64(min, max float64) float64

RandomFloat64 生成指定范围内的随机浮点数

func RandomInt

func RandomInt(min, max int) int

RandomInt 生成指定范围内的随机整数

func RandomString

func RandomString(length int, charset string) string

RandomString 生成指定长度的随机字符串

func ValidateCaptchaJSON

func ValidateCaptchaJSON(data []byte, expectedAnswer string) (bool, error)

ValidateCaptchaJSON 验证 JSON 格式的验证码

Types

type ArithmeticOp

type ArithmeticOp int

ArithmeticOp 算术运算符

const (
	OpAdd ArithmeticOp = iota
	OpSub
	OpMul
)

type ArithmeticStrategy

type ArithmeticStrategy struct {
	// contains filtered or unexported fields
}

ArithmeticStrategy 算术验证码策略

func NewArithmeticStrategy

func NewArithmeticStrategy(ops ...ArithmeticOp) *ArithmeticStrategy

NewArithmeticStrategy 创建算术验证码策略

func (*ArithmeticStrategy) Generate

func (s *ArithmeticStrategy) Generate(config CaptchaConfig) (*CaptchaImage, error)

Generate 生成算术验证码

func (*ArithmeticStrategy) Verify

func (s *ArithmeticStrategy) Verify(answer, expected string) bool

Verify 验证答案

type Captcha

type Captcha struct {
	// contains filtered or unexported fields
}

Captcha 验证码管理器

func New

func New(strategy Strategy, store Store, config ...CaptchaConfig) *Captcha

New 创建验证码管理器

func (*Captcha) EncodePNG

func (c *Captcha) EncodePNG(img *CaptchaImage) ([]byte, error)

EncodePNG 将验证码图片编码为 PNG

func (*Captcha) Generate

func (c *Captcha) Generate() (*CaptchaImage, error)

Generate 生成验证码

func (*Captcha) SetConfig

func (c *Captcha) SetConfig(config CaptchaConfig)

SetConfig 动态更新配置

func (*Captcha) SetStrategy

func (c *Captcha) SetStrategy(strategy Strategy)

SetStrategy 动态切换策略

func (*Captcha) Verify

func (c *Captcha) Verify(captchaID, answer string) bool

Verify 验证答案

type CaptchaConfig

type CaptchaConfig struct {
	Width    int
	Height   int
	Length   int
	MaxSkew  float64
	DotCount int
}

CaptchaConfig 验证码配置

func DefaultConfig

func DefaultConfig() CaptchaConfig

DefaultConfig 默认配置

type CaptchaImage

type CaptchaImage struct {
	Image     image.Image `json:"-"`
	Answer    string      `json:"answer"`
	CaptchaID string      `json:"captcha_id"`
	CreatedAt time.Time   `json:"created_at"`
}

CaptchaImage 验证码图片

func FromJSON

func FromJSON(data []byte) (*CaptchaImage, error)

FromJSON 从 JSON 恢复验证码(注意:Image 字段无法序列化)

func FromJSONWithImage

func FromJSONWithImage(data []byte) (*CaptchaImage, []byte, error)

FromJSONWithImage 从包含图片数据的 JSON 恢复验证码

func (*CaptchaImage) MarshalJSON

func (c *CaptchaImage) MarshalJSON() ([]byte, error)

MarshalJSON 实现 json.Marshaler 接口

func (*CaptchaImage) ToJSON

func (c *CaptchaImage) ToJSON() ([]byte, error)

ToJSON 将验证码转换为 JSON

func (*CaptchaImage) ToJSONWithImage

func (c *CaptchaImage) ToJSONWithImage(imageData []byte) ([]byte, error)

ToJSONWithImage 将验证码转换为包含图片数据的 JSON

func (*CaptchaImage) UnmarshalJSON

func (c *CaptchaImage) UnmarshalJSON(data []byte) error

UnmarshalJSON 实现 json.Unmarshaler 接口

type CaptchaJSON

type CaptchaJSON struct {
	CaptchaID string    `json:"captcha_id"`
	Answer    string    `json:"answer"`
	CreatedAt time.Time `json:"created_at"`
	ImageData []byte    `json:"image_data,omitempty"`
}

CaptchaJSON 验证码的 JSON 序列化结构

type CaptchaResponse

type CaptchaResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message,omitempty"`
	Data    struct {
		CaptchaID string `json:"captcha_id"`
		Image     string `json:"image"` // base64 编码的图片
	} `json:"data,omitempty"`
}

CaptchaResponse API 响应结构

type CaptchaVerifyRequest

type CaptchaVerifyRequest struct {
	CaptchaID string `json:"captcha_id"`
	Answer    string `json:"answer"`
}

CaptchaVerifyRequest 验证请求

type CaptchaVerifyResponse

type CaptchaVerifyResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message,omitempty"`
}

CaptchaVerifyResponse 验证响应

type ChineseStrategy

type ChineseStrategy struct {
	// contains filtered or unexported fields
}

ChineseStrategy 中文验证码策略

func NewChineseStrategy

func NewChineseStrategy(chars ...string) *ChineseStrategy

NewChineseStrategy 创建中文验证码策略

func (*ChineseStrategy) Generate

func (s *ChineseStrategy) Generate(config CaptchaConfig) (*CaptchaImage, error)

Generate 生成中文验证码

func (*ChineseStrategy) Verify

func (s *ChineseStrategy) Verify(answer, expected string) bool

Verify 验证答案

type ClickCaptchaData

type ClickCaptchaData struct {
	Image    *CaptchaImage `json:"-"`
	Targets  []ClickTarget `json:"targets"`
	Sequence []int         `json:"sequence"` // 正确的点击顺序
}

ClickCaptchaData 点击验证码数据

type ClickStrategy

type ClickStrategy struct {
	// contains filtered or unexported fields
}

ClickStrategy 点击验证码策略

func NewClickStrategy

func NewClickStrategy(targetCount, targetSize int) *ClickStrategy

NewClickStrategy 创建点击验证码策略

func (*ClickStrategy) Generate

func (s *ClickStrategy) Generate(config CaptchaConfig) (*CaptchaImage, error)

Generate 生成点击验证码

func (*ClickStrategy) GenerateWithTargets

func (s *ClickStrategy) GenerateWithTargets(config CaptchaConfig) (*ClickCaptchaData, error)

GenerateWithTargets 生成带目标数据的点击验证码

func (*ClickStrategy) Verify

func (s *ClickStrategy) Verify(answer, expected string) bool

Verify 验证点击顺序

func (*ClickStrategy) VerifyClickSequence

func (s *ClickStrategy) VerifyClickSequence(clicks []ClickTarget, targets []ClickTarget) bool

VerifyClickSequence 验证点击坐标序列

type ClickTarget

type ClickTarget struct {
	X      int    `json:"x"`
	Y      int    `json:"y"`
	Width  int    `json:"width"`
	Height int    `json:"height"`
	Label  string `json:"label"`
	Order  int    `json:"order"`
}

ClickTarget 点击目标

type DigitsStrategy

type DigitsStrategy struct{}

DigitsStrategy 数字验证码策略

func NewDigitsStrategy

func NewDigitsStrategy() *DigitsStrategy

NewDigitsStrategy 创建数字验证码策略

func (*DigitsStrategy) Generate

func (s *DigitsStrategy) Generate(config CaptchaConfig) (*CaptchaImage, error)

Generate 生成数字验证码

func (*DigitsStrategy) Verify

func (s *DigitsStrategy) Verify(answer, expected string) bool

Verify 验证答案

type GIFStrategy

type GIFStrategy struct {
	// contains filtered or unexported fields
}

GIFStrategy GIF 动画验证码策略

func NewGIFStrategy

func NewGIFStrategy(frameCount, delay int) *GIFStrategy

NewGIFStrategy 创建 GIF 动画验证码策略

func (*GIFStrategy) Generate

func (s *GIFStrategy) Generate(config CaptchaConfig) (*CaptchaImage, error)

Generate 生成 GIF 动画验证码

func (*GIFStrategy) GenerateGIF

func (s *GIFStrategy) GenerateGIF(config CaptchaConfig) ([]byte, *CaptchaImage, error)

GenerateGIF 生成 GIF 字节数据

func (*GIFStrategy) Verify

func (s *GIFStrategy) Verify(answer, expected string) bool

Verify 验证答案

type LettersStrategy

type LettersStrategy struct{}

LettersStrategy 字母验证码策略

func NewLettersStrategy

func NewLettersStrategy() *LettersStrategy

NewLettersStrategy 创建字母验证码策略

func (*LettersStrategy) Generate

func (s *LettersStrategy) Generate(config CaptchaConfig) (*CaptchaImage, error)

Generate 生成字母验证码

func (*LettersStrategy) Verify

func (s *LettersStrategy) Verify(answer, expected string) bool

Verify 验证答案

type MemoryStore

type MemoryStore struct {
	// contains filtered or unexported fields
}

MemoryStore 内存存储实现

func NewMemoryStore

func NewMemoryStore() *MemoryStore

NewMemoryStore 创建内存存储

func (*MemoryStore) Delete

func (s *MemoryStore) Delete(id string)

Delete 删除验证码

func (*MemoryStore) Get

func (s *MemoryStore) Get(id string) (string, bool)

Get 获取验证码答案

func (*MemoryStore) Set

func (s *MemoryStore) Set(id string, answer string, ttl time.Duration)

Set 存储验证码答案

type Store

type Store interface {
	// Set 存储验证码答案
	Set(id string, answer string, ttl time.Duration)
	// Get 获取验证码答案
	Get(id string) (string, bool)
	// Delete 删除验证码
	Delete(id string)
}

Store 验证码存储接口

type Strategy

type Strategy interface {
	// Generate 生成验证码图片
	Generate(config CaptchaConfig) (*CaptchaImage, error)
	// Verify 验证答案是否正确
	Verify(answer, expected string) bool
}

Strategy 验证码策略接口

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL