driver_digit.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright 2017 Eric Zhou. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package base64Captcha
  15. import "math/rand"
  16. //DriverDigit config for captcha-engine-digit.
  17. type DriverDigit struct {
  18. // Height png height in pixel.
  19. Height int
  20. // Width Captcha png width in pixel.
  21. Width int
  22. // DefaultLen Default number of digits in captcha solution.
  23. Length int
  24. // MaxSkew max absolute skew factor of a single digit.
  25. MaxSkew float64
  26. // DotCount Number of background circles.
  27. DotCount int
  28. }
  29. //NewDriverDigit creates a driver of digit
  30. func NewDriverDigit(height int, width int, length int, maxSkew float64, dotCount int) *DriverDigit {
  31. return &DriverDigit{Height: height, Width: width, Length: length, MaxSkew: maxSkew, DotCount: dotCount}
  32. }
  33. //DefaultDriverDigit is a default driver of digit
  34. var DefaultDriverDigit = NewDriverDigit(80, 240, 5, 0.7, 80)
  35. //GenerateIdQuestionAnswer creates captcha content and answer
  36. func (d *DriverDigit) GenerateIdQuestionAnswer() (id, q, a string) {
  37. id = RandomId()
  38. digits := randomDigits(d.Length)
  39. a = parseDigitsToString(digits)
  40. return id, a, a
  41. }
  42. //DrawCaptcha creates digit captcha item
  43. func (d *DriverDigit) DrawCaptcha(content string) (item Item, err error) {
  44. // Initialize PRNG.
  45. itemDigit := NewItemDigit(d.Width, d.Height, d.DotCount, d.MaxSkew)
  46. //parse digits to string
  47. digits := stringToFakeByte(content)
  48. itemDigit.calculateSizes(d.Width, d.Height, len(digits))
  49. // Randomly position captcha inside the image.
  50. maxx := d.Width - (itemDigit.width+itemDigit.dotSize)*len(digits) - itemDigit.dotSize
  51. maxy := d.Height - itemDigit.height - itemDigit.dotSize*2
  52. var border int
  53. if d.Width > d.Height {
  54. border = d.Height / 5
  55. } else {
  56. border = d.Width / 5
  57. }
  58. x := rand.Intn(maxx-border*2) + border
  59. y := rand.Intn(maxy-border*2) + border
  60. // Draw digits.
  61. for _, n := range digits {
  62. itemDigit.drawDigit(digitFontData[n], x, y)
  63. x += itemDigit.width + itemDigit.dotSize
  64. }
  65. // Draw strike-through line.
  66. itemDigit.strikeThrough()
  67. // Apply wave distortion.
  68. itemDigit.distort(rand.Float64()*(10-5)+5, rand.Float64()*(200-100)+100)
  69. // Fill image with random circles.
  70. itemDigit.fillWithCircles(d.DotCount, itemDigit.dotSize)
  71. return itemDigit, nil
  72. }