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 Collect
95
96 func Collect()
97
98Collect deletes expired or used captchas from the internal storage. It is
99called automatically by New function every CollectNum generated captchas,
100but still exported to enable freeing memory manually if needed.
101
102Collection is launched in a new goroutine.
103
104### func New
105
106 func New(length int) (id string)
107
108New creates a new captcha of the given length, saves it in the internal
109storage, and returns its id.
110
111### func RandomDigits
112
113 func RandomDigits(length int) []byte
114
115RandomDigits returns a byte slice of the given length containing random
116digits in range 0-9.
117
118### func Reload
119
120 func Reload(id string) bool
121
122Reload generates and remembers new digits for the given captcha id. This
123function returns false if there is no captcha with the given id.
124
125After calling this function, the image or audio presented to a user must be
126refreshed to show the new captcha representation (WriteImage and WriteAudio
127will write the new one).
128
129### func Server
130
131 func Server(w, h int) http.Handler
132
133Server returns a handler that serves HTTP requests with image or
134audio representations of captchas. Image dimensions are accepted as
135arguments. The server decides which captcha to serve based on the last URL
136path component: file name part must contain a captcha id, file extension —
137its format (PNG or WAV).
138
139For example, for file name "B9QTvDV1RXbVJ3Ac.png" it serves an image captcha
140with id "B9QTvDV1RXbVJ3Ac", and for "B9QTvDV1RXbVJ3Ac.wav" it serves the
141same captcha in audio format.
142
143To serve a captcha as a downloadable file, the URL must be constructed in
144such a way as if the file to serve is in "download" subdirectory:
145"/download/B9QTvDV1RXbVJ3Ac.wav".
146
147To reload captcha (get a different solution for the same captcha id), append
148"?reload=x" to URL, where x may be anything (for example, current time or a
149random number to make browsers refetch an image instead of loading it from
150cache).
151
152### func SetCustomStore
153
154 func SetCustomStore(s Store)
155
156SetCustomStore sets custom storage for captchas, replacing the default
157memory store. This function must be called before generating any captchas.
158
159### func Verify
160
161 func Verify(id string, digits []byte) bool
162
163Verify returns true if the given digits are the ones that were used to
164create the given captcha id.
165
166The function deletes the captcha with the given id from the internal
167storage, so that the same captcha can't be verified anymore.
168
169### func VerifyString
170
171 func VerifyString(id string, digits string) bool
172
173VerifyString is like Verify, but accepts a string of digits. It removes
174spaces and commas from the string, but any other characters, apart from
175digits and listed above, will cause the function to return false.
176
177### func WriteAudio
178
179 func WriteAudio(w io.Writer, id string) os.Error
180
181WriteAudio writes WAV-encoded audio representation of the captcha with the
182given id.
183
184### func WriteImage
185
186 func WriteImage(w io.Writer, id string, width, height int) os.Error
187
188WriteImage writes PNG-encoded image representation of the captcha with the
189given id. The image will have the given width and height.
190
191
192Types
193-----
194
195``` go
196type Audio struct {
197 // contains unexported fields
198}
199```
200
201
202### func NewAudio
203
204 func NewAudio(digits []byte) *Audio
205
206NewImage returns a new audio captcha with the given digits, where each digit
207must be in range 0-9.
208
209### func (*Audio) EncodedLen
210
211 func (a *Audio) EncodedLen() int
212
213EncodedLen returns the length of WAV-encoded audio captcha.
214
215### func (*Audio) WriteTo
216
217 func (a *Audio) WriteTo(w io.Writer) (n int64, err os.Error)
218
219WriteTo writes captcha audio in WAVE format into the given io.Writer, and
220returns the number of bytes written and an error if any.
221
222``` go
223type Image struct {
224 *image.NRGBA
225 // contains unexported fields
226}
227```
228
229
230### func NewImage
231
232 func NewImage(digits []byte, width, height int) *Image
233
234NewImage returns a new captcha image of the given width and height with the
235given digits, where each digit must be in range 0-9.
236
237### func (*Image) WriteTo
238
239 func (img *Image) WriteTo(w io.Writer) (int64, os.Error)
240
241WriteTo writes captcha image in PNG format into the given writer.
242
243``` go
244type Store interface {
245 // Set sets the digits for the captcha id.
246 Set(id string, digits []byte)
247
248 // Get returns stored digits for the captcha id. Clear indicates
249 // whether the captcha must be deleted from the store.
250 Get(id string, clear bool) (digits []byte)
251
252 // Collect deletes expired captchas from the store. For custom stores
253 // this method is not called automatically, it is only wired to the
254 // package's Collect function. Custom stores must implement their own
255 // procedure for calling Collect, for example, in Set method.
256 Collect()
257}
258```
259
260An object implementing Store interface can be registered with SetCustomStore
261function to handle storage and retrieval of captcha ids and solutions for
262them, replacing the default memory store.
263
264### func NewMemoryStore
265
266 func NewMemoryStore(collectNum int, expiration int64) Store
267
268NewMemoryStore returns a new standard memory store for captchas with the
269given collection threshold and expiration time in seconds. The returned
270store must be registered with SetCustomStore to replace the default one.
271
272
273Bugs
274----
275
276* [Not our bug] Google Chrome 10 plays unsigned 8-bit PCM WAVE
277audio on Mac with horrible distortions. Issue:
278http://code.google.com/p/chromium/issues/detail?id=70730.
279This has been fixed, and version 12 will play them properly.
280
281* While Image conforms to io.WriterTo interface, its WriteTo
282method returns 0 instead of the actual bytes written because png.Encode
283doesn't report this.
284
285
286Subdirectories
287--------------
288
289* capgen
290* example
291* generate