Go package captcha implements generation and verification of image and audio CAPTCHAs.

Package captcha

⚠️ Warning: this captcha can be broken by advanced OCR captcha breaking algorithms.

import "github.com/dchest/captcha"

Package captcha implements generation and verification of image and audio CAPTCHAs.

A captcha solution is the sequence of digits 0-9 with the defined length. There are two captcha representations: image and audio.

An image representation is a PNG-encoded image with the solution printed on it in such a way that makes it hard for computers to solve it using OCR.

An audio representation is a WAVE-encoded (8 kHz unsigned 8-bit) sound with the spoken solution (currently in English, Russian, Chinese, and Japanese). To make it hard for computers to solve audio captcha, the voice that pronounces numbers has random speed and pitch, and there is a randomly generated background noise mixed into the sound.

This package doesn't require external files or libraries to generate captcha representations; it is self-contained.

To make captchas one-time, the package includes a memory storage that stores captcha ids, their solutions, and expiration time. Used captchas are removed from the store immediately after calling Verify or VerifyString, while unused captchas (user loaded a page with captcha, but didn't submit the form) are collected automatically after the predefined expiration time. Developers can also provide custom store (for example, which saves captcha ids and solutions in database) by implementing Store interface and registering the object with SetCustomStore.

Captchas are created by calling New, which returns the captcha id. Their representations, though, are created on-the-fly by calling WriteImage or WriteAudio functions. Created representations are not stored anywhere, but subsequent calls to these functions with the same id will write the same captcha solution. Reload function will create a new different solution for the provided captcha, allowing users to "reload" captcha if they can't solve the displayed one without reloading the whole page. Verify and VerifyString are used to verify that the given solution is the right one for the given captcha id.

Server provides an http.Handler which can serve image and audio representations of captchas automatically from the URL. It can also be used to reload captchas. Refer to Server function documentation for details, or take a look at the example in "capexample" subdirectory.

Examples

Image

Audio

Constants

const (
    // Default number of digits in captcha solution.
    DefaultLen = 6
    // The number of captchas created that triggers garbage collection used
    // by default store.
    CollectNum = 100
    // Expiration time of captchas used by default store.
    Expiration = 10 * time.Minute
)
const (
    // Standard width and height of a captcha image.
    StdWidth  = 240
    StdHeight = 80
)

Variables

var (
    ErrNotFound = errors.New("captcha: id not found")
)

Functions

func New

func New() string

New creates a new captcha with the standard length, saves it in the internal storage and returns its id.

func NewLen

func NewLen(length int) (id string)

NewLen is just like New, but accepts length of a captcha solution as the argument.

func RandomDigits

func RandomDigits(length int) (b []byte)

RandomDigits returns a byte slice of the given length containing pseudorandom numbers in range 0-9. The slice can be used as a captcha solution.

func Reload

func Reload(id string) bool

Reload generates and remembers new digits for the given captcha id. This function returns false if there is no captcha with the given id.

After calling this function, the image or audio presented to a user must be refreshed to show the new captcha representation (WriteImage and WriteAudio will write the new one).

func Server

func Server(imgWidth, imgHeight int) http.Handler

Server returns a handler that serves HTTP requests with image or audio representations of captchas. Image dimensions are accepted as arguments. The server decides which captcha to serve based on the last URL path component: file name part must contain a captcha id, file extension — its format (PNG or WAV).

For example, for file name "LBm5vMjHDtdUfaWYXiQX.png" it serves an image captcha with id "LBm5vMjHDtdUfaWYXiQX", and for "LBm5vMjHDtdUfaWYXiQX.wav" it serves the same captcha in audio format.

To serve a captcha as a downloadable file, the URL must be constructed in such a way as if the file to serve is in the "download" subdirectory: "/download/LBm5vMjHDtdUfaWYXiQX.wav".

To reload captcha (get a different solution for the same captcha id), append "?reload=x" to URL, where x may be anything (for example, current time or a random number to make browsers refetch an image instead of loading it from cache).

By default, the Server serves audio in English language. To serve audio captcha in one of the other supported languages, append "lang" value, for example, "?lang=ru".

func SetCustomStore

func SetCustomStore(s Store)

SetCustomStore sets custom storage for captchas, replacing the default memory store. This function must be called before generating any captchas.

func Verify

func Verify(id string, digits []byte) bool

Verify returns true if the given digits are the ones that were used to create the given captcha id.

The function deletes the captcha with the given id from the internal storage, so that the same captcha can't be verified anymore.

func VerifyString

func VerifyString(id string, digits string) bool

VerifyString is like Verify, but accepts a string of digits. It removes spaces and commas from the string, but any other characters, apart from digits and listed above, will cause the function to return false.

func WriteAudio

func WriteAudio(w io.Writer, id string, lang string) error

WriteAudio writes WAV-encoded audio representation of the captcha with the given id and the given language. If there are no sounds for the given language, English is used.

func WriteImage

func WriteImage(w io.Writer, id string, width, height int) error

WriteImage writes PNG-encoded image representation of the captcha with the given id. The image will have the given width and height.

Types

type Audio struct {
    // contains unexported fields
}

func NewAudio

func NewAudio(id string, digits []byte, lang string) *Audio

NewAudio returns a new audio captcha with the given digits, where each digit must be in range 0-9. Digits are pronounced in the given language. If there are no sounds for the given language, English is used.

Possible values for lang are "en", "ja", "ru", "zh".

func (*Audio) EncodedLen

func (a *Audio) EncodedLen() int

EncodedLen returns the length of WAV-encoded audio captcha.

func (*Audio) WriteTo

func (a *Audio) WriteTo(w io.Writer) (n int64, err error)

WriteTo writes captcha audio in WAVE format into the given io.Writer, and returns the number of bytes written and an error if any.

type Image struct {
    *image.Paletted
    // contains unexported fields
}

func NewImage

func NewImage(id string, digits []byte, width, height int) *Image

NewImage returns a new captcha image of the given width and height with the given digits, where each digit must be in range 0-9.

func (*Image) WriteTo

func (m *Image) WriteTo(w io.Writer) (int64, error)

WriteTo writes captcha image in PNG format into the given writer.

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

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

An object implementing Store interface can be registered with SetCustomStore function to handle storage and retrieval of captcha ids and solutions for them, replacing the default memory store.

It is the responsibility of an object to delete expired and used captchas when necessary (for example, the default memory store collects them in Set method after the certain amount of captchas has been stored.)

func NewMemoryStore

func NewMemoryStore(collectNum int, expiration time.Duration) Store

NewMemoryStore returns a new standard memory store for captchas with the given collection threshold and expiration time in seconds. The returned store must be registered with SetCustomStore to replace the default one.

Owner
Dmitry Chestnykh
Founder of @coding-robots. Invented "I Write Like". Previously created BlogJet (acquired) and StableLib. Interested in cryptography and perfect code.
Dmitry Chestnykh
Comments
  • Added RealDigits function to get the digits used to create a captcha.

    Added RealDigits function to get the digits used to create a captcha.

    This new function provides increased flexibility for the captcha system developer. They can see what the correct answer to a given captcha is supposed to be, exposing that information for use in other features, beyond just captcha.Verify(...)

  • Too difficult to recognize the number

    Too difficult to recognize the number

    great work! But numbers stay too close and sometimes overlap. Do you have an image size / ratio recommendation or design an param to set the difficulty?

  • Usage with Gorilla Mux

    Usage with Gorilla Mux

    I've been trying to modify your example to use Gorilla Mux's routing but keep coming up with a 404 error when accessing /captcha/:

    router.Methods("GET").Path("/captcha/").Handler(captcha.Server(captcha.StdWidth, captcha.StdHeight))

    My example code:

    http://stackoverflow.com/questions/27614932/how-do-i-convert-a-handle-to-a-handlefunc

    (I should also mention I'm new to Go ;)

  • too difficult to recognize audio captcha

    too difficult to recognize audio captcha

    Hi, I found it really hard to recognize numbers (particularly, 0 1 5) from background noise when trying audio captcha in Chinese, even with earphone.

    I'm a native listener, and I think most Chinese users would have the same feeling as me. As for me, passing the default audio captcha within 10 attempts is nearly impossible.

    Could you please consider it, to replace the hard-to-recognize voices? What's more, it is reasonable to allow developers to adjust the difficulty (for example, noise intensity). Thanks.

  • provide `New() (id , solution string)`

    provide `New() (id , solution string)`

    Hi,

    I am in a case where i want the api to give both id and solution when invoking its service.

    Some explanations, I need that while using captcha within a JSON API. Currently i only send back an id, with these new api i will be able to cipher the solution using a private key, and signing the message, which i will answer along the id. Using that i can validate any captcha issued by my api even though the service was restarted (i use no persistent db for captcha service), or, worst case, the api has totally changed because i only need to check the signed message, uncipher the solution and compare it with the JIT provided solution.

  • Security issue: Can't set custom security headers

    Security issue: Can't set custom security headers

    We can setup a captcha server by using: http.Handle("/captcha/", captcha.Server(captcha.StdWidth, captcha.StdHeight)

    However, this does not allow setting custom headers for enhancing security such as:

    Access-Control-Allow-Origin
    X-Frame-Options
    X-Content-Type-Options
    X-XSS-Protection
    

    This leaves the application vulnerable to various attacks

  • problem in julienschmidt router

    problem in julienschmidt router

    hi I've been trying to modify your example to use julienschmidt routing but keep coming up with a 404 error when accessing /captcha/

    instead of your code in default http route i have used this code r.Handler(http.MethodGet,"/captcha/" ,captcha.Server(captcha.StdWidth, captcha.StdHeight)) but still i do not access to "captcha" directory and .png file too. how could i use your library with julienschmidt http routing?

  • How can i use captcha in Gin Framework?

    How can i use captcha in Gin Framework?

    	if err := formTemplate.Execute(w, &d); err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    	}
    

    i think formTemplate.Execute is the keyword to generate a captch. But i use gin with gin multemplate.

    How can i use captcha in Gin framework?

  • image.go make func encodedPNG() to EncodedPNG()

    image.go make func encodedPNG() to EncodedPNG()

    in image.go make func encodedPNG() []byte to EncodedPNG() []byte, it can support other http framework like "iris" "gin" !!!

    and 1. I recommend separate storage interfaces and image generator ,and delete storage interface, For example, com.google.code.kaptcha, it only do the createText(),createImage(). other job like storage, i will choose like "redis" "mysql" "mongo"....

    do not use "Id",and do not use "captcha.VerifyString(id string, digits string)" , I think the id just like session,but some people like me will use phone to Instead of id,and use custom validation

  • Using AJAX

    Using AJAX

    I am trying to implement the captcha with AJAX. Currently when a user submits just digits(runs through the Verify function in captcha.go) the captcha image becomes broken. This occurs regardless if the Reload button is triggered through JavaScript. Implementing strings or strings with digits however allows reload of image but the captcha image breaks again when only digits are entered using AJAX.

    I think this is mainly because the entire web page needs to be parsed again and pass in the captcha.New() string through go templates.

    So I don't see any way to combine AJAX with this set up as if I have to refresh the entire web page to pass in the captchaId string through golang templates then using AJAX would be pointless. Any ideas to work around this?

  • Func VerifyString it works incorrectly

    Func VerifyString it works incorrectly

    I was advised by a colleague to use this repository, as he was able to implement protection. When I started testing I ran into a problem -- verify and verifystring display false all the time.

    code:

    func main() {
    	id := captcha.New()
    	path_img, _ := os.Create("data.png")
    
    	var w io.WriterTo
    	digits := captcha.RandomDigits(6)
    	w = captcha.NewImage(id, digits, 256, 128)
    	w.WriteTo(path_img)
    
    	var x string
    	fmt.Scan(&x)
    	fmt.Println(
    		"result: ", captcha.VerifyString(id, x), 
    		"\ngenerate digits:", digits, 
    		"\nid:", id,
    	)
    }
    

    result from console: image

  • Make Server accept a config struct

    Make Server accept a config struct

    Currently, Server, accepts imgWidth and imgHeight. I'd like to change it to accept a configuration struct to make it easier to expand it without API change:

    type ServerConfig struct {
       ImgWidth  int
       ImgHeight int
    }
    
    func Server(config *ServerConfig) http.Handler
    

    Another idea is to make top-level functions methods on config (renamed Server or something):

    type Server struct {
       ImgWidth     int
       ImgHeight    int
       Store        Store
       CollectNum   int
       Expiration   time.Time
    }
    
    func (c *Server) Handler() http.Handler
    
  • Distinguish between expired captchas and invalid submissions?

    Distinguish between expired captchas and invalid submissions?

    It seems that there is no way to do this, though it would be helpful. I'd like to alert my users with "expired captcha" or "invalid captcha" instead of just reporting failure.

    This is pretty minor, of course. By and large, this is a great package. Thanks for building and sharing. You've saved me quite a bit of effort/frustration/etc.

Pbm - Package ppm implements a Portable Bit Map (PBM) image decoder and encoder written in Go

Package pbm import "github.com/slashformotion/pbm" Package pbm implements a Portable Bit Map (PBM) image decoder and encoder. The supported image col

Jan 5, 2022
A captcha library written in golang
A captcha library written in golang

gocaptcha 一个简单的Go语言实现的验证码 图片实例 简介 基于Golang实现的图片验证码生成库,可以实现随机字母个数,随机直线,随机噪点等。可以设置任意多字体,每个验证码随机选一种字体展示。 实例 使用: go get github.com/lifei6671/gocaptcha/

Dec 29, 2022
A Go-language library for the automatic generation of image collages.

CollageCreator is a Go-language library for the automatic generation of image collages.

Jan 29, 2022
darkroom - An image proxy with changeable storage backends and image processing engines with focus on speed and resiliency.
darkroom - An image proxy with changeable storage backends and image processing engines with focus on speed and resiliency.

Darkroom - Yet Another Image Proxy Introduction Darkroom combines the storage backend and the image processor and acts as an Image Proxy on your image

Dec 6, 2022
An API which allows you to upload an image and responds with the same image, stripped of EXIF data

strip-metadata This is an API which allows you to upload an image and responds with the same image, stripped of EXIF data. How to run You need to have

Nov 25, 2021
Easily customizable Social image (or Open graph image) generator

fancycard Easily customizable Social image (or Open graph image) generator Built with Go, Gin, GoQuery and Chromedp Build & Run Simply, Clone this rep

Jan 14, 2022
Imgpreview - Tiny image previews for HTML while the original image is loading
Imgpreview - Tiny image previews for HTML while the original image is loading

imgpreview This is a Go program that generates tiny blurry previews for images t

May 22, 2022
Go bindings for audio capture and playback with ALSA and libasound

Go ALSA bindings These bindings allow capture and playback of audio via ALSA using the alsa-lib library. Installation go get github.com/cocoonlife/goa

Nov 26, 2022
Process audio files with pipelined DSP framework
Process audio files with pipelined DSP framework

phono is a command for audio processing. It's build on top of pipelined DSP framework. Installation Prerequisites: lame to enable mp3 encoding To link

Oct 4, 2022
Cgo bindings to PulseAudio's Simple API, for easily playing or capturing raw audio.

pulse-simple Cgo bindings to PulseAudio's Simple API, for easily playing or capturing raw audio. The full Simple API is supported, including channel m

Dec 17, 2022
asciigrid is a Go package that implements decoder and encoder for the Esri ASCII grid format, also known as ARC/INFO ASCII GRID.

asciigrid asciigrid is a Go package that implements decoder and encoder for the Esri ASCII grid format, also known as ARC/INFO ASCII GRID. Install go

Jul 3, 2022
Procedural texture generation package.
Procedural texture generation package.

Texture Generation A package for the procedural generation of textures. Based on the ideas contained in the Bryce 3D deep texture editor. More example

Sep 8, 2022
Package qrcode implements a QR Code encoder

A matrix barcode, Arbitrary content may be encoded, with URLs being a popular choice

Nov 1, 2021
Go package for decoding and encoding TARGA image format

tga tga is a Go package for decoding and encoding TARGA image format. It supports RLE and raw TARGA images with 8/15/16/24/32 bits per pixel, monochro

Sep 26, 2022
Go package for fast high-level image processing powered by libvips C library

bimg Small Go package for fast high-level image processing using libvips via C bindings, providing a simple programmatic API. bimg was designed to be

Jan 2, 2023
Imaging is a simple image processing package for Go
Imaging is a simple image processing package for Go

Imaging Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.). All the image process

Dec 30, 2022
Go Perceptual image hashing package

goimagehash Inspired by imagehash A image hashing library written in Go. ImageHash supports: Average hashing Difference hashing Perception hashing Wav

Jan 3, 2023
golang package to find the K most dominant/prominent colors in an image
golang package to find the K most dominant/prominent colors in an image

prominentcolor Find the K most dominant colors in an image The Kmeans function returns the K most dominant colors in the image, ordered in the order o

Nov 7, 2022
package for convert DataURLs to image

convert base64 DataURLs to image

Oct 18, 2021