{"id":13393789,"url":"https://github.com/mojocn/base64Captcha","last_synced_at":"2025-03-13T19:31:50.205Z","repository":{"id":39569513,"uuid":"113986555","full_name":"mojocn/base64Captcha","owner":"mojocn","description":"captcha of base64 image string","archived":false,"fork":false,"pushed_at":"2025-01-09T08:53:50.000Z","size":10992,"stargazers_count":2185,"open_issues_count":5,"forks_count":274,"subscribers_count":50,"default_branch":"master","last_synced_at":"2025-03-11T20:06:13.421Z","etag":null,"topics":["anti-spam","arithmetic-captcha","audio-captchas","base64","captcha","captcha-generator","go","golang","image-captcha","yanzhengma"],"latest_commit_sha":null,"homepage":"https://captcha.mojotv.cn/.netlify/functions/captcha","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mojocn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":[],"patreon":"mojotech","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null}},"created_at":"2017-12-12T12:17:07.000Z","updated_at":"2025-03-11T04:03:42.000Z","dependencies_parsed_at":"2022-07-14T07:20:36.828Z","dependency_job_id":"d262238d-cb05-4339-9adf-c2155b8d6821","html_url":"https://github.com/mojocn/base64Captcha","commit_stats":{"total_commits":185,"total_committers":23,"mean_commits":8.043478260869565,"dds":0.5783783783783784,"last_synced_commit":"5ab86bd6f333aad3936f912fc52b411168dcd4a7"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mojocn%2Fbase64Captcha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mojocn%2Fbase64Captcha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mojocn%2Fbase64Captcha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mojocn%2Fbase64Captcha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mojocn","download_url":"https://codeload.github.com/mojocn/base64Captcha/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243469211,"owners_count":20295710,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anti-spam","arithmetic-captcha","audio-captchas","base64","captcha","captcha-generator","go","golang","image-captcha","yanzhengma"],"created_at":"2024-07-30T17:01:00.276Z","updated_at":"2025-03-13T19:31:47.681Z","avatar_url":"https://github.com/mojocn.png","language":"Go","readme":"# A flexible and various captcha package\n![Test](https://github.com/mojocn/base64Captcha/workflows/Test/badge.svg)\n[![Go Report Card](https://goreportcard.com/badge/github.com/mojocn/base64Captcha)](https://goreportcard.com/report/github.com/mojocn/base64Captcha)\n[![GoDoc](https://godoc.org/github.com/mojocn/base64Captcha?status.svg)](https://godoc.org/github.com/mojocn/base64Captcha)\n[![Build Status](https://travis-ci.org/mojocn/base64Captcha.svg?branch=master)](https://travis-ci.org/mojocn/base64Captcha)\n[![codecov](https://codecov.io/gh/mojocn/base64Captcha/branch/master/graph/badge.svg)](https://codecov.io/gh/mojocn/base64Captcha)\n![stability-stable](https://img.shields.io/badge/stability-stable-brightgreen.svg)\n[![Foundation](https://img.shields.io/badge/Golang-Foundation-green.svg)](http://golangfoundation.org)\n\nBase64captcha supports any unicode character and can easily be customized to support Math Chinese Korean Japanese Russian Arabic etc.\n\n\n## 1. 📖📖📖 Doc \u0026 Demo\n\n* [English](https://godoc.org/github.com/mojocn/base64Captcha)\n* [中文文档](https://mojotv.cn/go/refactor-base64-captcha)\n* [Playground](https://captcha.mojotv.cn)\n\n## 2. 🚀🚀🚀 Quick start\n### 2.1 🎬🎬🎬 Use history version\n[Tag v1.2.2](https://github.com/mojocn/base64Captcha/tree/v1.2.2)\n\n` go get github.com/mojocn/base64Captcha@v1.2.2`\n\nor edit your `go.mod` file to\n\n`github.com/mojocn/base64Captcha@v1.2.2`\n\n### 2.2 📥📥📥 Download package\n    go get -u github.com/mojocn/base64Captcha\nFor Gopher from mainland China without VPN `go get golang.org/x/image` failure solution:\n- go version \u003e 1.11\n- set env `GOPROXY=https://goproxy.io`\n\n### 2.3 🏂🏂🏂 How to code with base64Captcha\n\n#### 2.3.1 🏇🏇🏇 Implement [Store interface](interface_store.go) or use build-in memory store\n\n- [Build-in Memory Store](store_memory.go)\n\n```go\ntype Store interface {\n\t// Set sets the digits for the captcha id.\n\tSet(id string, value string)\n\n\t// Get returns stored digits for the captcha id. Clear indicates\n\t// whether the captcha must be deleted from the store.\n\tGet(id string, clear bool) string\n\t\n    //Verify captcha's answer directly\n\tVerify(id, answer string, clear bool) bool\n}\n\n```\n\n#### 2.3.2 🏄🏄🏄 Implement [Driver interface](interface_driver.go) or use one of build-in drivers\nThere are some build-in drivers:\n1. [Build-in Driver Digit](driver_digit.go)  \n2. [Build-in Driver String](driver_string.go)\n3. [Build-in Driver Math](driver_math.go)\n4. [Build-in Driver Chinese](driver_chinese.go)\n\n```go\n// Driver captcha interface for captcha engine to to write staff\ntype Driver interface {\n\t//DrawCaptcha draws binary item\n\tDrawCaptcha(content string) (item Item, err error)\n\t//GenerateIdQuestionAnswer creates rand id, content and answer\n\tGenerateIdQuestionAnswer() (id, q, a string)\n}\n```\n\n#### 2.3.3 🚴🚴🚴 ‍Core code [captcha.go](captcha.go)\n`captcha.go` is the entry of base64Captcha which is quite simple.\n```go\npackage base64Captcha\n\nimport (\n\t\"math/rand\"\n\t\"time\"\n)\n\nfunc init() {\n\t//init rand seed\n\trand.Seed(time.Now().UnixNano())\n}\n\n// Captcha captcha basic information.\ntype Captcha struct {\n\tDriver Driver\n\tStore  Store\n}\n\n//NewCaptcha creates a captcha instance from driver and store\nfunc NewCaptcha(driver Driver, store Store) *Captcha {\n\treturn \u0026Captcha{Driver: driver, Store: store}\n}\n\n//Generate generates a random id, base64 image string or an error if any\nfunc (c *Captcha) Generate() (id, b64s string, err error) {\n\tid,content, answer := c.Driver.GenerateIdQuestionAnswer()\n\titem, err := c.Driver.DrawCaptcha(content)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tc.Store.Set(id, answer)\n\tb64s = item.EncodeB64string()\n\treturn\n}\n\n//Verify by a given id key and remove the captcha value in store,\n//return boolean value.\n//if you has multiple captcha instances which share a same store.\n//You may want to call `store.Verify` method instead.\nfunc (c *Captcha) Verify(id, answer string, clear bool) (match bool) {\n\tmatch = c.Store.Get(id, clear) == answer\n\treturn\n}\n\n```\n#### 2.3.4 🚵🚵🚵 ‍Generate Base64(image/audio) string\n```go\nfunc (c *Captcha) Generate() (id, b64s string, err error) {\n\tid,content, answer := c.Driver.GenerateIdQuestionAnswer()\n\titem, err := c.Driver.DrawCaptcha(content)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tc.Store.Set(id, answer)\n\tb64s = item.EncodeB64string()\n\treturn\n}\n```\n#### 2.3.5 🤸🤸🤸 Verify Answer\n```go\n//if you has multiple captcha instances which shares a same store. You may want to use `store.Verify` method instead.\n//Verify by given id key and remove the captcha value in store, return boolean value.\nfunc (c *Captcha) Verify(id, answer string, clear bool) (match bool) {\n\tmatch = c.Store.Get(id, clear) == answer\n\treturn\n}\n```\n\n#### 2.3.6 🏃🏃🏃 ‍Full Example\n\n```go\n// example of HTTP server that uses the captcha package.\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/mojocn/base64Captcha\"\n\t\"log\"\n\t\"net/http\"\n)\n\n//configJsonBody json request body.\ntype configJsonBody struct {\n\tId            string\n\tCaptchaType   string\n\tVerifyValue   string\n\tDriverAudio   *base64Captcha.DriverAudio\n\tDriverString  *base64Captcha.DriverString\n\tDriverChinese *base64Captcha.DriverChinese\n\tDriverMath    *base64Captcha.DriverMath\n\tDriverDigit   *base64Captcha.DriverDigit\n}\n\nvar store = base64Captcha.DefaultMemStore\n\n// base64Captcha create http handler\nfunc generateCaptchaHandler(w http.ResponseWriter, r *http.Request) {\n\t//parse request parameters\n\tdecoder := json.NewDecoder(r.Body)\n\tvar param configJsonBody\n\terr := decoder.Decode(\u0026param)\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\tdefer r.Body.Close()\n\tvar driver base64Captcha.Driver\n\n\t//create base64 encoding captcha\n\tswitch param.CaptchaType {\n\tcase \"audio\":\n\t\tdriver = param.DriverAudio\n\tcase \"string\":\n\t\tdriver = param.DriverString.ConvertFonts()\n\tcase \"math\":\n\t\tdriver = param.DriverMath.ConvertFonts()\n\tcase \"chinese\":\n\t\tdriver = param.DriverChinese.ConvertFonts()\n\tdefault:\n\t\tdriver = param.DriverDigit\n\t}\n\tc := base64Captcha.NewCaptcha(driver, store)\n\tid, b64s, err := c.Generate()\n\tbody := map[string]interface{}{\"code\": 1, \"data\": b64s, \"captchaId\": id, \"msg\": \"success\"}\n\tif err != nil {\n\t\tbody = map[string]interface{}{\"code\": 0, \"msg\": err.Error()}\n\t}\n\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\tjson.NewEncoder(w).Encode(body)\n}\n\n// base64Captcha verify http handler\nfunc captchaVerifyHandle(w http.ResponseWriter, r *http.Request) {\n\n\t//parse request json body\n\tdecoder := json.NewDecoder(r.Body)\n\tvar param configJsonBody\n\terr := decoder.Decode(\u0026param)\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\tdefer r.Body.Close()\n\t//verify the captcha\n\tbody := map[string]interface{}{\"code\": 0, \"msg\": \"failed\"}\n\tif store.Verify(param.Id, param.VerifyValue, true) {\n\t\tbody = map[string]interface{}{\"code\": 1, \"msg\": \"ok\"}\n\t}\n\n\t//set json response\n\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\n\tjson.NewEncoder(w).Encode(body)\n}\n\n//start a net/http server\nfunc main() {\n\t//serve Vuejs+ElementUI+Axios Web Application\n\thttp.Handle(\"/\", http.FileServer(http.Dir(\"./static\")))\n\n\t//api for create captcha\n\thttp.HandleFunc(\"/api/getCaptcha\", generateCaptchaHandler)\n\n\t//api for verify captcha\n\thttp.HandleFunc(\"/api/verifyCaptcha\", captchaVerifyHandle)\n\n\tfmt.Println(\"Server is at :8777\")\n\tif err := http.ListenAndServe(\":8777\", nil); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n```\n\n#### 2.3.7 Example Use Etcd as store\n[captcha with etcd database as store](captcha_with_etcd_exmaple.md)\n\n## 3. 🎨🎨🎨 Customization\nYou can customize your captcha display image by implementing [interface driver](interface_driver.go) \nand [interface item](interface_item.go).\n\nThere are some example for your reference.\n1. [DriverMath](driver_math.go)\n2. [DriverChinese](driver_chinese.go)\n3. [ItemChar](item_char.go)\n\n***You can even design the [captcha struct](captcha.go) to whatever you prefer.***\n\n## 4. 💖💖💖 Thanks\n- [dchest/captha](https://github.com/dchest/captcha)\n- [@slayercat](https://github.com/slayercat)\n- [@amzyang](https://github.com/amzyang)\n- [@Luckyboys](https://github.com/Luckyboys)\n- [@hi-sb](https://github.com/hi-sb)\n\n## 5. 🍭🍭🍭 Licence\n\nbase64Captcha source code is licensed under the Apache Licence, Version 2.0\n(http://www.apache.org/licenses/LICENSE-2.0.html).\n","funding_links":["https://patreon.com/mojotech"],"categories":["开源类库","Go","Miscellaneous","Generowanie","Open source library","常用验证码库","其他杂项","杂项","Microsoft Office","其他","Uncategorized"],"sub_categories":["图形处理","Strings","Graphics Processing","Uncategorized","暂未分类","Advanced Console UIs","未分类的","交流","暂未分类这些库被放在这里是因为其他类别似乎都不适合。"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmojocn%2Fbase64Captcha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmojocn%2Fbase64Captcha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmojocn%2Fbase64Captcha/lists"}