README.md (view raw)
1Package captcha
2=====================
3
4 import "github.com/dchest/captcha"
5
6Package captcha implements generation and verification of image and audio
7CAPTCHAs.
8
9A captcha solution is the sequence of digits 0-9 with the defined length.
10There are two captcha representations: image and audio.
11
12An image representation is a PNG-encoded image with the solution printed on
13it in such a way that makes it hard for computers to solve it using OCR.
14
15An audio representation is a WAVE-encoded (8 kHz unsigned 8-bit) sound
16with the spoken solution (currently in English). To make it hard for
17computers to solve audio captcha, the voice that pronounces numbers has
18random speed and pitch, and there is a randomly generated background noise
19mixed into the sound.
20
21This package doesn't require external files or libraries to generate captcha
22representations; it is self-contained.
23
24To make captchas one-time, the package includes a memory storage that stores
25captcha ids, their solutions, and expiration time. Used captchas are removed
26from the store immediately after calling Verify or VerifyString, while
27unused captchas (user loaded a page with captcha, but didn't submit the
28form) are collected automatically after the predefined expiration time.
29Developers can also provide custom store (for example, which saves captcha
30ids and solutions in database) by implementing Store interface and
31registering the object with SetCustomStore.
32
33Captchas are created by calling New, which returns the captcha id. Their
34representations, though, are created on-the-fly by calling WriteImage or
35WriteAudio functions. Created representations are not stored anywhere, so
36subsequent calls to these functions with the same id will write the same
37captcha solution, but with a different random representation. Reload
38function will create a new different solution for the provided captcha,
39allowing users to "reload" captcha if they can't solve the displayed one
40without reloading the whole page. Verify and VerifyString are used to
41verify that the given solution is the right one for the given captcha id.
42
43Server provides an http.Handler which can serve image and audio
44representations of captchas automatically from the URL. It can also be used
45to reload captchas. Refer to Server function documentation for details, or
46take a look at the example in "example" subdirectory.
47
48
49Examples
50--------
51
52![Image](https://github.com/dchest/captcha/raw/master/capgen/example.png)
53
54[Audio](https://github.com/dchest/captcha/raw/master/capgen/example.wav)
55
56
57Constants
58---------
59
60``` go
61const (
62 // Standard number of digits in captcha.
63 StdLength = 6
64 // The number of captchas created that triggers garbage collection used
65 // by default store.
66 CollectNum = 100
67 // Expiration time of captchas used by default store.
68 Expiration = 10 * 60 // 10 minutes
69
70)
71```
72
73``` go
74const (
75 // Standard width and height of a captcha image.
76 StdWidth = 240
77 StdHeight = 80
78)
79```
80
81
82Variables
83---------
84
85``` go
86var ErrNotFound = os.NewError("captcha with the given id not found")
87```
88
89
90
91Functions
92---------
93
94### func New
95
96 func New(length int) (id string)
97
98New creates a new captcha of the given length, saves it in the internal
99storage, and returns its id.
100
101### func RandomDigits
102
103 func RandomDigits(length int) []byte
104
105RandomDigits returns a byte slice of the given length containing random
106digits in range 0-9.
107
108### func Reload
109
110 func Reload(id string) bool
111
112Reload generates and remembers new digits for the given captcha id. This
113function returns false if there is no captcha with the given id.
114
115After calling this function, the image or audio presented to a user must be
116refreshed to show the new captcha representation (WriteImage and WriteAudio
117will write the new one).
118
119### func Server
120
121 func Server(imgWidth, imgHeight int) http.Handler
122
123Server returns a handler that serves HTTP requests with image or
124audio representations of captchas. Image dimensions are accepted as
125arguments. The server decides which captcha to serve based on the last URL
126path component: file name part must contain a captcha id, file extension —
127its format (PNG or WAV).
128
129For example, for file name "B9QTvDV1RXbVJ3Ac.png" it serves an image captcha
130with id "B9QTvDV1RXbVJ3Ac", and for "B9QTvDV1RXbVJ3Ac.wav" it serves the
131same captcha in audio format.
132
133To serve a captcha as a downloadable file, the URL must be constructed in
134such a way as if the file to serve is in the "download" subdirectory:
135"/download/B9QTvDV1RXbVJ3Ac.wav".
136
137To reload captcha (get a different solution for the same captcha id), append
138"?reload=x" to URL, where x may be anything (for example, current time or a
139random number to make browsers refetch an image instead of loading it from
140cache).
141
142### func SetCustomStore
143
144 func SetCustomStore(s Store)
145
146SetCustomStore sets custom storage for captchas, replacing the default
147memory store. This function must be called before generating any captchas.
148
149### func Verify
150
151 func Verify(id string, digits []byte) bool
152
153Verify returns true if the given digits are the ones that were used to
154create the given captcha id.
155
156The function deletes the captcha with the given id from the internal
157storage, so that the same captcha can't be verified anymore.
158
159### func VerifyString
160
161 func VerifyString(id string, digits string) bool
162
163VerifyString is like Verify, but accepts a string of digits. It removes
164spaces and commas from the string, but any other characters, apart from
165digits and listed above, will cause the function to return false.
166
167### func WriteAudio
168
169 func WriteAudio(w io.Writer, id string) os.Error
170
171WriteAudio writes WAV-encoded audio representation of the captcha with the
172given id.
173
174### func WriteImage
175
176 func WriteImage(w io.Writer, id string, width, height int) os.Error
177
178WriteImage writes PNG-encoded image representation of the captcha with the
179given id. The image will have the given width and height.
180
181
182Types
183-----
184
185``` go
186type Audio struct {
187 // contains unexported fields
188}
189```
190
191
192### func NewAudio
193
194 func NewAudio(digits []byte) *Audio
195
196NewImage returns a new audio captcha with the given digits, where each digit
197must be in range 0-9.
198
199### func (*Audio) EncodedLen
200
201 func (a *Audio) EncodedLen() int
202
203EncodedLen returns the length of WAV-encoded audio captcha.
204
205### func (*Audio) WriteTo
206
207 func (a *Audio) WriteTo(w io.Writer) (n int64, err os.Error)
208
209WriteTo writes captcha audio in WAVE format into the given io.Writer, and
210returns the number of bytes written and an error if any.
211
212``` go
213type Image struct {
214 *image.NRGBA
215 // contains unexported fields
216}
217```
218
219
220### func NewImage
221
222 func NewImage(digits []byte, width, height int) *Image
223
224NewImage returns a new captcha image of the given width and height with the
225given digits, where each digit must be in range 0-9.
226
227### func (*Image) WriteTo
228
229 func (img *Image) WriteTo(w io.Writer) (int64, os.Error)
230
231WriteTo writes captcha image in PNG format into the given writer.
232
233``` go
234type Store interface {
235 // Set sets the digits for the captcha id.
236 Set(id string, digits []byte)
237
238 // Get returns stored digits for the captcha id. Clear indicates
239 // whether the captcha must be deleted from the store.
240 Get(id string, clear bool) (digits []byte)
241}
242```
243
244An object implementing Store interface can be registered with SetCustomStore
245function to handle storage and retrieval of captcha ids and solutions for
246them, replacing the default memory store.
247
248It is the responsibility of an object to delete expired and used captchas
249when necessary (for example, the default memory store collects them in Set
250method after the certain amount of captchas has been stored.)
251
252### func NewMemoryStore
253
254 func NewMemoryStore(collectNum int, expiration int64) Store
255
256NewMemoryStore returns a new standard memory store for captchas with the
257given collection threshold and expiration time in seconds. The returned
258store must be registered with SetCustomStore to replace the default one.
259
260
261Bugs
262----
263
264* [Not our bug] Google Chrome 10 plays unsigned 8-bit PCM WAVE
265audio on Mac with horrible distortions. Issue:
266http://code.google.com/p/chromium/issues/detail?id=70730.
267This has been fixed, and version 12 will play them properly.
268
269* While Image conforms to io.WriterTo interface, its WriteTo
270method returns 0 instead of the actual bytes written because png.Encode
271doesn't report this.
272
273
274Subdirectories
275--------------
276
277* capgen
278* example
279* generate