// Copyright 2017 Eric Zhou. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package base64Captcha import "math/rand" //DriverDigit config for captcha-engine-digit. type DriverDigit struct { // Height png height in pixel. Height int // Width Captcha png width in pixel. Width int // DefaultLen Default number of digits in captcha solution. Length int // MaxSkew max absolute skew factor of a single digit. MaxSkew float64 // DotCount Number of background circles. DotCount int } //NewDriverDigit creates a driver of digit func NewDriverDigit(height int, width int, length int, maxSkew float64, dotCount int) *DriverDigit { return &DriverDigit{Height: height, Width: width, Length: length, MaxSkew: maxSkew, DotCount: dotCount} } //DefaultDriverDigit is a default driver of digit var DefaultDriverDigit = NewDriverDigit(80, 240, 5, 0.7, 80) //GenerateIdQuestionAnswer creates captcha content and answer func (d *DriverDigit) GenerateIdQuestionAnswer() (id, q, a string) { id = RandomId() digits := randomDigits(d.Length) a = parseDigitsToString(digits) return id, a, a } //DrawCaptcha creates digit captcha item func (d *DriverDigit) DrawCaptcha(content string) (item Item, err error) { // Initialize PRNG. itemDigit := NewItemDigit(d.Width, d.Height, d.DotCount, d.MaxSkew) //parse digits to string digits := stringToFakeByte(content) itemDigit.calculateSizes(d.Width, d.Height, len(digits)) // Randomly position captcha inside the image. maxx := d.Width - (itemDigit.width+itemDigit.dotSize)*len(digits) - itemDigit.dotSize maxy := d.Height - itemDigit.height - itemDigit.dotSize*2 var border int if d.Width > d.Height { border = d.Height / 5 } else { border = d.Width / 5 } x := rand.Intn(maxx-border*2) + border y := rand.Intn(maxy-border*2) + border // Draw digits. for _, n := range digits { itemDigit.drawDigit(digitFontData[n], x, y) x += itemDigit.width + itemDigit.dotSize } // Draw strike-through line. itemDigit.strikeThrough() // Apply wave distortion. itemDigit.distort(rand.Float64()*(10-5)+5, rand.Float64()*(200-100)+100) // Fill image with random circles. itemDigit.fillWithCircles(d.DotCount, itemDigit.dotSize) return itemDigit, nil }