MCPcopy
hub / github.com/mojocn/base64Captcha

github.com/mojocn/base64Captcha @v1.3.8 sqlite

repository ↗ · DeepWiki ↗ · release v1.3.8 ↗
241 symbols 723 edges 44 files 96 documented · 40%
README

A flexible and various captcha package

Test Go Report Card GoDoc Build Status codecov stability-stable Foundation

Base64captcha supports any unicode character and can easily be customized to support Math Chinese Korean Japanese Russian Arabic etc.

1. 📖📖📖 Doc & Demo

2. 🚀🚀🚀 Quick start

2.1 🎬🎬🎬 Use history version

Tag v1.2.2

go get github.com/mojocn/base64Captcha@v1.2.2

or edit your go.mod file to

github.com/mojocn/base64Captcha@v1.2.2

2.2 📥📥📥 Download package

go get -u github.com/mojocn/base64Captcha

For Gopher from mainland China without VPN go get golang.org/x/image failure solution: - go version > 1.11 - set env GOPROXY=https://goproxy.io

2.3 🏂🏂🏂 How to code with base64Captcha

2.3.1 🏇🏇🏇 Implement Store interface or use build-in memory store

type Store interface {
    // Set sets the digits for the captcha id.
    Set(id string, value string)

    // Get returns stored digits for the captcha id. Clear indicates
    // whether the captcha must be deleted from the store.
    Get(id string, clear bool) string

    //Verify captcha's answer directly
    Verify(id, answer string, clear bool) bool
}

2.3.2 🏄🏄🏄 Implement Driver interface or use one of build-in drivers

There are some build-in drivers: 1. Build-in Driver Digit
2. Build-in Driver String 3. Build-in Driver Math 4. Build-in Driver Chinese

// Driver captcha interface for captcha engine to to write staff
type Driver interface {
    //DrawCaptcha draws binary item
    DrawCaptcha(content string) (item Item, err error)
    //GenerateIdQuestionAnswer creates rand id, content and answer
    GenerateIdQuestionAnswer() (id, q, a string)
}

2.3.3 🚴🚴🚴 ‍Core code captcha.go

captcha.go is the entry of base64Captcha which is quite simple.

package base64Captcha

import (
    "math/rand"
    "time"
)

func init() {
    //init rand seed
    rand.Seed(time.Now().UnixNano())
}

// Captcha captcha basic information.
type Captcha struct {
    Driver Driver
    Store  Store
}

//NewCaptcha creates a captcha instance from driver and store
func NewCaptcha(driver Driver, store Store) *Captcha {
    return &Captcha{Driver: driver, Store: store}
}

//Generate generates a random id, base64 image string or an error if any
func (c *Captcha) Generate() (id, b64s string, err error) {
    id,content, answer := c.Driver.GenerateIdQuestionAnswer()
    item, err := c.Driver.DrawCaptcha(content)
    if err != nil {
        return "", "", err
    }
    c.Store.Set(id, answer)
    b64s = item.EncodeB64string()
    return
}

//Verify by a given id key and remove the captcha value in store,
//return boolean value.
//if you has multiple captcha instances which share a same store.
//You may want to call `store.Verify` method instead.
func (c *Captcha) Verify(id, answer string, clear bool) (match bool) {
    match = c.Store.Get(id, clear) == answer
    return
}

2.3.4 🚵🚵🚵 ‍Generate Base64(image/audio) string

func (c *Captcha) Generate() (id, b64s string, err error) {
    id,content, answer := c.Driver.GenerateIdQuestionAnswer()
    item, err := c.Driver.DrawCaptcha(content)
    if err != nil {
        return "", "", err
    }
    c.Store.Set(id, answer)
    b64s = item.EncodeB64string()
    return
}

2.3.5 🤸🤸🤸 Verify Answer

//if you has multiple captcha instances which shares a same store. You may want to use `store.Verify` method instead.
//Verify by given id key and remove the captcha value in store, return boolean value.
func (c *Captcha) Verify(id, answer string, clear bool) (match bool) {
    match = c.Store.Get(id, clear) == answer
    return
}

2.3.6 🏃🏃🏃 ‍Full Example

// example of HTTP server that uses the captcha package.
package main

import (
    "encoding/json"
    "fmt"
    "github.com/mojocn/base64Captcha"
    "log"
    "net/http"
)

//configJsonBody json request body.
type configJsonBody struct {
    Id            string
    CaptchaType   string
    VerifyValue   string
    DriverAudio   *base64Captcha.DriverAudio
    DriverString  *base64Captcha.DriverString
    DriverChinese *base64Captcha.DriverChinese
    DriverMath    *base64Captcha.DriverMath
    DriverDigit   *base64Captcha.DriverDigit
}

var store = base64Captcha.DefaultMemStore

// base64Captcha create http handler
func generateCaptchaHandler(w http.ResponseWriter, r *http.Request) {
    //parse request parameters
    decoder := json.NewDecoder(r.Body)
    var param configJsonBody
    err := decoder.Decode(&param)
    if err != nil {
        log.Println(err)
    }
    defer r.Body.Close()
    var driver base64Captcha.Driver

    //create base64 encoding captcha
    switch param.CaptchaType {
    case "audio":
        driver = param.DriverAudio
    case "string":
        driver = param.DriverString.ConvertFonts()
    case "math":
        driver = param.DriverMath.ConvertFonts()
    case "chinese":
        driver = param.DriverChinese.ConvertFonts()
    default:
        driver = param.DriverDigit
    }
    c := base64Captcha.NewCaptcha(driver, store)
    id, b64s, err := c.Generate()
    body := map[string]interface{}{"code": 1, "data": b64s, "captchaId": id, "msg": "success"}
    if err != nil {
        body = map[string]interface{}{"code": 0, "msg": err.Error()}
    }
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    json.NewEncoder(w).Encode(body)
}

// base64Captcha verify http handler
func captchaVerifyHandle(w http.ResponseWriter, r *http.Request) {

    //parse request json body
    decoder := json.NewDecoder(r.Body)
    var param configJsonBody
    err := decoder.Decode(&param)
    if err != nil {
        log.Println(err)
    }
    defer r.Body.Close()
    //verify the captcha
    body := map[string]interface{}{"code": 0, "msg": "failed"}
    if store.Verify(param.Id, param.VerifyValue, true) {
        body = map[string]interface{}{"code": 1, "msg": "ok"}
    }

    //set json response
    w.Header().Set("Content-Type", "application/json; charset=utf-8")

    json.NewEncoder(w).Encode(body)
}

//start a net/http server
func main() {
    //serve Vuejs+ElementUI+Axios Web Application
    http.Handle("/", http.FileServer(http.Dir("./static")))

    //api for create captcha
    http.HandleFunc("/api/getCaptcha", generateCaptchaHandler)

    //api for verify captcha
    http.HandleFunc("/api/verifyCaptcha", captchaVerifyHandle)

    fmt.Println("Server is at :8777")
    if err := http.ListenAndServe(":8777", nil); err != nil {
        log.Fatal(err)
    }
}

2.3.7 Example Use Etcd as store

captcha with etcd database as store

3. 🎨🎨🎨 Customization

You can customize your captcha display image by implementing interface driver and interface item.

There are some example for your reference. 1. DriverMath 2. DriverChinese 3. ItemChar

You can even design the captcha struct to whatever you prefer.

4. 💖💖💖 Thanks

5. 🍭🍭🍭 Licence

base64Captcha source code is licensed under the Apache Licence, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html).

Extension points exported contracts — how you extend this code

Driver (Interface)
Driver captcha interface for captcha engine to to write staff [6 implementers]
interface_driver.go
Item (Interface)
Item is captcha item interface [3 implementers]
interface_item.go
Store (Interface)
Store An object implementing Store interface can be registered with SetCustomStore function to handle storage and retrie [2 …
interface_store.go
FontsStorage (Interface)
FontsStorage interface for working with fonts [1 implementers]
interface_fonts.go

Core symbols most depended-on inside this repo

Set
called by 24
interface_store.go
RandomId
called by 18
random_math.go
randomDigits
called by 13
util.go
Get
called by 11
interface_store.go
NewMemoryStore
called by 10
store_memory.go
RandText
called by 9
random_math.go
LoadFontByName
called by 9
interface_fonts.go
randIntRange
called by 8
random_math.go

Shape

Function 134
Method 65
Struct 38
Interface 4

Languages

Go100%

Modules by API surface

item_digit.go16 symbols
item_char.go12 symbols
item_char_test.go11 symbols
store_memory_test.go10 symbols
random_math.go10 symbols
item_audio.go10 symbols
store_sync_map_test.go8 symbols
store_sync_map.go8 symbols
store_memory.go8 symbols
random_math_test.go8 symbols
util_test.go7 symbols
util.go7 symbols

Dependencies from manifests, versioned

github.com/golang/freetypev0.0.0-2017060900350 · 1×
golang.org/x/imagev0.23.0 · 1×

For agents

$ claude mcp add base64Captcha \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact