Rename "numbers" to "digits" everywhere. Plus fix comments.
Dmitry Chestnykh dmitry@codingrobots.com
Sun, 24 Apr 2011 13:23:17 +0200
6 files changed,
111 insertions(+),
111 deletions(-)
M
audio.go
→
audio.go
@@ -13,15 +13,15 @@
const sampleRate = 8000 // Hz var ( - // Length of the longest number sound - longestNumSndLen int + // Length of the longest digit sound. + longestDigitSndLen int endingBeepSound []byte ) func init() { - for _, v := range numberSounds { - if longestNumSndLen < len(v) { - longestNumSndLen = len(v) + for _, v := range digitSounds { + if longestDigitSndLen < len(v) { + longestDigitSndLen = len(v) } } endingBeepSound = changeSpeed(beepSound, 1.4)@@ -31,56 +31,55 @@ type Audio struct {
body *bytes.Buffer } -// NewImage returns a new audio captcha with the given slice of numbers, where -// each number must be in range 0-9. -func NewAudio(numbers []byte) *Audio { - numsnd := make([][]byte, len(numbers)) +// NewImage returns a new audio captcha with the given digits, where each digit +// must be in range 0-9. +func NewAudio(digits []byte) *Audio { + numsnd := make([][]byte, len(digits)) nsdur := 0 - for i, n := range numbers { - snd := randomizedNumSound(n) + for i, n := range digits { + snd := randomizedDigitSound(n) nsdur += len(snd) numsnd[i] = snd } - // Intervals between numbers (including beginning) - intervals := make([]int, len(numbers)+1) + // Random intervals between digits (including beginning). + intervals := make([]int, len(digits)+1) intdur := 0 for i := range intervals { - // 1 to 3 seconds - dur := rnd(sampleRate, sampleRate*3) + dur := rnd(sampleRate, sampleRate*3) // 1 to 3 seconds intdur += dur intervals[i] = dur } - // Background noise - bg := makeBackgroundSound(longestNumSndLen*len(numbers) + intdur) - // -- + // Generate background sound. + bg := makeBackgroundSound(longestDigitSndLen*len(digits) + intdur) + // Create buffer and write audio to it. a := new(Audio) sil := makeSilence(sampleRate / 5) bufcap := 3*len(beepSound) + 2*len(sil) + len(bg) + len(endingBeepSound) a.body = bytes.NewBuffer(make([]byte, 0, bufcap)) - // Prelude, three beeps + // Write prelude, three beeps. a.body.Write(beepSound) a.body.Write(sil) a.body.Write(beepSound) a.body.Write(sil) a.body.Write(beepSound) - // Numbers + // Write digits. pos := intervals[0] for i, v := range numsnd { mixSound(bg[pos:], v) pos += len(v) + intervals[i+1] } a.body.Write(bg) - // Ending + // Write ending (one beep). a.body.Write(endingBeepSound) return a } -// NewRandomAudio generates a sequence of random numbers with the given length, -// and returns a new audio captcha with this numbers, and the sequence of -// numbers itself. -func NewRandomAudio(length int) (a *Audio, numbers []byte) { - numbers = randomNumbers(length) - a = NewAudio(numbers) +// NewRandomAudio generates a sequence of random digits with the given length, +// and returns a new audio captcha with these digits, and the sequence of +// digits itself. +func NewRandomAudio(length int) (a *Audio, digits []byte) { + digits = randomDigits(length) + a = NewAudio(digits) return }@@ -137,25 +136,25 @@ }
// changeSpeed returns new PCM bytes from the bytes with the speed and pitch // changed to the given value that must be in range [0, x]. -func changeSpeed(a []byte, pitch float64) []byte { - b := make([]byte, int(math.Floor(float64(len(a))*pitch))) +func changeSpeed(a []byte, speed float64) []byte { + b := make([]byte, int(math.Floor(float64(len(a))*speed))) var p float64 for _, v := range a { - for i := int(p); i < int(p+pitch); i++ { + for i := int(p); i < int(p+speed); i++ { b[i] = v } - p += pitch + p += speed } return b } -// rndFloat64n returns a random float64 number in range [from, to]. -func rndFloat64n(from, to float64) float64 { +// rndf returns a random float64 number in range [from, to]. +func rndf(from, to float64) float64 { return (to-from)*rand.Float64() + from } func randomSpeed(a []byte) []byte { - pitch := rndFloat64n(0.9, 1.2) + pitch := rndf(0.9, 1.2) return changeSpeed(a, pitch) }@@ -192,18 +191,18 @@
func makeBackgroundSound(length int) []byte { b := makeWhiteNoise(length, 8) for i := 0; i < length/(sampleRate/10); i++ { - snd := numberSounds[rand.Intn(10)] - snd = changeSpeed(reversedSound(snd), rndFloat64n(0.8, 1.4)) + snd := digitSounds[rand.Intn(10)] + snd = changeSpeed(reversedSound(snd), rndf(0.8, 1.4)) place := rand.Intn(len(b) - len(snd)) - setSoundLevel(snd, rndFloat64n(0.5, 1.2)) + setSoundLevel(snd, rndf(0.5, 1.2)) mixSound(b[place:], snd) } - setSoundLevel(b, rndFloat64n(0.2, 0.3)) + setSoundLevel(b, rndf(0.2, 0.3)) return b } -func randomizedNumSound(n byte) []byte { - s := randomSpeed(numberSounds[n]) - setSoundLevel(s, rndFloat64n(0.7, 1.3)) +func randomizedDigitSound(n byte) []byte { + s := randomSpeed(digitSounds[n]) + setSoundLevel(s, rndf(0.7, 1.3)) return s }
M
captcha.go
→
captcha.go
@@ -8,80 +8,80 @@ "io"
"os" ) -// Standard number of numbers in captcha +// Standard number of digits in captcha. const StdLength = 6 var globalStore = newStore() -// randomNumbers return a byte slice of the given length containing random -// numbers in range 0-9. -func randomNumbers(length int) []byte { - n := make([]byte, length) - if _, err := io.ReadFull(rand.Reader, n); err != nil { +// randomDigits return a byte slice of the given length containing random +// digits in range 0-9. +func randomDigits(length int) []byte { + d := make([]byte, length) + if _, err := io.ReadFull(rand.Reader, d); err != nil { panic(err) } - for i := range n { - n[i] %= 10 + for i := range d { + d[i] %= 10 } - return n + return d } // New creates a new captcha of the given length, saves it in the internal // storage, and returns its id. func New(length int) (id string) { id = uniuri.New() - globalStore.saveCaptcha(id, randomNumbers(length)) + globalStore.saveCaptcha(id, randomDigits(length)) return } -// Reload generates and remembers new numbers for the given captcha id. This +// 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 Reload(id string) bool { - oldns := globalStore.getNumbers(id) - if oldns == nil { + old := globalStore.getDigits(id) + if old == nil { return false } - globalStore.saveCaptcha(id, randomNumbers(len(oldns))) + globalStore.saveCaptcha(id, randomDigits(len(old))) return true } // WriteImage writes PNG-encoded image representation of the captcha with the // given id. The image will have the given width and height. func WriteImage(w io.Writer, id string, width, height int) os.Error { - ns := globalStore.getNumbers(id) - if ns == nil { + d := globalStore.getDigits(id) + if d == nil { return os.NewError("captcha id not found") } - _, err := NewImage(ns, width, height).WriteTo(w) + _, err := NewImage(d, width, height).WriteTo(w) return err } // WriteAudio writes WAV-encoded audio representation of the captcha with the // given id. func WriteAudio(w io.Writer, id string) os.Error { - ns := globalStore.getNumbers(id) - if ns == nil { + d := globalStore.getDigits(id) + if d == nil { return os.NewError("captcha id not found") } - _, err := NewAudio(ns).WriteTo(w) + _, err := NewAudio(d).WriteTo(w) return err } -// Verify returns true if the given numbers are the numbers that were used to +// 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 Verify(id string, numbers []byte) bool { - realns := globalStore.getNumbersClear(id) - if realns == nil { +func Verify(id string, digits []byte) bool { + reald := globalStore.getDigitsClear(id) + if reald == nil { return false } - return bytes.Equal(numbers, realns) + return bytes.Equal(digits, reald) } // Collect deletes expired and used captchas from the internal
M
image.go
→
image.go
@@ -10,7 +10,7 @@ "time"
) const ( - // Standard width and height for captcha image + // Standard width and height of a captcha image. StdWidth = 300 StdHeight = 80@@ -30,8 +30,8 @@ rand.Seed(time.Seconds())
} // NewImage returns a new captcha image of the given width and height with the -// given slice of numbers, where each number must be in range 0-9. -func NewImage(numbers []byte, width, height int) *Image { +// given digits, where each digit must be in range 0-9. +func NewImage(digits []byte, width, height int) *Image { img := new(Image) img.NRGBA = image.NewNRGBA(width, height) img.primaryColor = image.NRGBAColor{@@ -40,31 +40,31 @@ uint8(rand.Intn(129)),
uint8(rand.Intn(129)), 0xFF, } - // Calculate sizes - img.calculateSizes(width, height, len(numbers)) - // Draw background (10 random circles of random brightness) + // Calculate sizes. + img.calculateSizes(width, height, len(digits)) + // Draw background (10 random circles of random brightness). img.fillWithCircles(10, img.dotSize) - // Randomly position captcha inside the image - maxx := width - (img.numWidth+img.dotSize)*len(numbers) - img.dotSize + // Randomly position captcha inside the image. + maxx := width - (img.numWidth+img.dotSize)*len(digits) - img.dotSize maxy := height - img.numHeight - img.dotSize*2 x := rnd(img.dotSize*2, maxx) y := rnd(img.dotSize*2, maxy) - // Draw numbers - for _, n := range numbers { - img.drawNumber(font[n], x, y) + // Draw digits. + for _, n := range digits { + img.drawDigit(font[n], x, y) x += img.numWidth + img.dotSize } - // Draw strike-through line + // Draw strike-through line. img.strikeThrough() return img } -// NewRandomImage generates a sequence of random numbers with the given length, +// NewRandomImage generates a sequence of random digits with the given length, // and returns a new captcha image of the given width and height with generated -// numbers printed on it, and the sequence of numbers itself. -func NewRandomImage(length, width, height int) (img *Image, numbers []byte) { - numbers = randomNumbers(length) - img = NewImage(numbers, width, height) +// digits printed on it, and the sequence of digits itself. +func NewRandomImage(length, width, height int) (img *Image, digits []byte) { + digits = randomDigits(length) + img = NewImage(digits, width, height) return }@@ -77,35 +77,35 @@ return 0, png.Encode(w, img)
} func (img *Image) calculateSizes(width, height, ncount int) { - // Goal: fit all numbers inside the image. + // Goal: fit all digits inside the image. var border int if width > height { border = height / 5 } else { border = width / 5 } - // Convert everything to floats for calculations - w := float64(width-border*2) - h := float64(height-border*2) - // fw takes into account 1-dot spacing between numbers + // Convert everything to floats for calculations. + w := float64(width - border*2) + h := float64(height - border*2) + // fw takes into account 1-dot spacing between digits. fw := float64(fontWidth) + 1 fh := float64(fontHeight) nc := float64(ncount) - // Calculate the width of a single number taking into account only the - // width of the image + // Calculate the width of a single digit taking into account only the + // width of the image. nw := w / nc - // Calculate the height of a number from this width + // Calculate the height of a digit from this width. nh := nw * fh / fw - // Number height too large? + // Digit too high? if nh > h { - // Fit numbers based on height + // Fit digits based on height. nh = h nw = fw / fh * nh } - // Calculate dot size + // Calculate dot size. img.dotSize = int(nh / fh) // Save everything, making the actual width smaller by 1 dot to account - // for spacing between numbers + // for spacing between digits. img.numWidth = int(nw) img.numHeight = int(nh) - img.dotSize }@@ -169,7 +169,7 @@ img.drawCircle(img.primaryColor, x, y, r)
} } -func (img *Image) drawNumber(number []byte, x, y int) { +func (img *Image) drawDigit(digit []byte, x, y int) { skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew)) xs := float64(x) minr := img.dotSize / 2 // minumum radius@@ -177,13 +177,14 @@ maxr := img.dotSize/2 + img.dotSize/4 // maximum radius
y += rnd(-minr, minr) for yy := 0; yy < fontHeight; yy++ { for xx := 0; xx < fontWidth; xx++ { - if number[yy*fontWidth+xx] != blackChar { + if digit[yy*fontWidth+xx] != blackChar { continue } - // introduce random variations + // Introduce random variations. or := rnd(minr, maxr) ox := x + (xx * img.dotSize) + rnd(0, or/2) oy := y + (yy * img.dotSize) + rnd(0, or/2) + img.drawCircle(img.primaryColor, ox, oy, or) } xs += skf
M
originals/generate.go
→
originals/generate.go
@@ -46,8 +46,8 @@ writeFileRep(pcm, name+".wav", "\t")
fmt.Fprintf(pcm, "}\n") } -func writeNumbers(pcm io.Writer) { - fmt.Fprintf(pcm, "var numberSounds = [][]byte{\n") +func writeDigitSounds(pcm io.Writer) { + fmt.Fprintf(pcm, "var digitSounds = [][]byte{\n") for i := 0; i <= 9; i++ { fmt.Fprintf(pcm, "\t{ // %d\n\t\t", i) writeFileRep(pcm, fmt.Sprintf("%d.wav", i), "\t\t")@@ -76,6 +76,6 @@
// Byte slices contain raw 8 kHz unsigned 8-bit PCM data (without wav header). `) - writeNumbers(pcm) + writeDigitSounds(pcm) writeSingle(pcm, "beep") }
M
sounds.go
→
sounds.go
@@ -11,7 +11,7 @@ }
// Byte slices contain raw 8 kHz unsigned 8-bit PCM data (without wav header). -var numberSounds = [][]byte{ +var digitSounds = [][]byte{ { // 0 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x80,
M
store.go
→
store.go
@@ -38,11 +38,11 @@ s.exp = list.New()
return s } -// saveCaptcha saves the captcha id and the corresponding numbers. -func (s *store) saveCaptcha(id string, ns []byte) { +// saveCaptcha saves the captcha id and the corresponding digits. +func (s *store) saveCaptcha(id string, digits []byte) { s.mu.Lock() defer s.mu.Unlock() - s.ids[id] = ns + s.ids[id] = digits s.exp.PushBack(expValue{time.Seconds(), id}) s.colNum++ if s.colNum > CollectNum {@@ -51,20 +51,20 @@ s.colNum = 0
} } -// getNumbers returns the numbers for the given id. -func (s *store) getNumbers(id string) (ns []byte) { +// getDigits returns the digits for the given id. +func (s *store) getDigits(id string) (digits []byte) { s.mu.RLock() defer s.mu.RUnlock() - ns, _ = s.ids[id] + digits, _ = s.ids[id] return } -// getNumbersClear returns the numbers for the given id, and removes them from +// getDigitsClear returns the digits for the given id, and removes them from // the store. -func (s *store) getNumbersClear(id string) (ns []byte) { +func (s *store) getDigitsClear(id string) (digits []byte) { s.mu.Lock() defer s.mu.Unlock() - ns, ok := s.ids[id] + digits, ok := s.ids[id] if !ok { return }