start.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package gocaptcha
  2. import (
  3. "app.yhyue.com/moapp/jybase/go-xweb/httpsession"
  4. "app.yhyue.com/moapp/jybase/redis"
  5. "fmt"
  6. "image/color"
  7. "log"
  8. "math/rand"
  9. "net/http"
  10. "time"
  11. )
  12. // 图形验证码大小
  13. const (
  14. dx = 200
  15. dy = 80
  16. fontSize = 75
  17. Rn = 1
  18. CollectNum = 50
  19. Expiration = 10 * time.Minute
  20. )
  21. // 生成的字符集
  22. var (
  23. TextCharacters = []rune("ACDEFGHJKLMNPQRSTUVWXY2456789")
  24. globalStore = NewMemoryStore(CollectNum, Expiration)
  25. )
  26. // 初始化字体文件
  27. func InitCaptcha() {
  28. err := SetFontPath("./fonts/")
  29. if err != nil {
  30. log.Println(err)
  31. }
  32. }
  33. // RandText 生成随机字体.
  34. func RandText(num int) string {
  35. textNum := len(TextCharacters)
  36. text := make([]rune, num)
  37. for i := 0; i < num; i++ {
  38. text[i] = TextCharacters[rand.Intn(textNum)]
  39. }
  40. return string(text)
  41. }
  42. // RandLightColor 随机生成浅色底色.
  43. func RandLightColor(n int) color.RGBA {
  44. // 为每个颜色分量生成一个128到255之间的随机数
  45. red := rand.Intn(100/n) + 156 + (100 - 100/n)
  46. green := rand.Intn(100/n) + 156 + (100 - 100/n)
  47. blue := rand.Intn(100/n) + 156 + (100 - 100/n)
  48. // Alpha 通道设置为完全不透明
  49. a := uint8(rand.Intn(8) + 247)
  50. return color.RGBA{R: uint8(red), G: uint8(green), B: uint8(blue), A: a}
  51. }
  52. func Get(sess *httpsession.Session, checkCode string, w http.ResponseWriter, r *http.Request) {
  53. code := RandText(4)
  54. log.Println(code)
  55. cacheKey := fmt.Sprintf("captcha_times_%s", sess.Id())
  56. var (
  57. // 计次数
  58. times = redis.GetInt("other", cacheKey)
  59. ttl = redis.GetTTL("other", cacheKey)
  60. rn = times%6 + 1
  61. //跳色
  62. cc = RandLightColor(rn) //
  63. )
  64. // cc.A = uint8(rand.Intn(10) + 245)
  65. captchaImage := New(dx, dy, cc).
  66. DrawBorder(RandDeepColor())
  67. if times < 3 {
  68. captchaImage = captchaImage.DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
  69. DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(42), rn).
  70. DrawLine(NewBeeline(), RandDeepColor()).
  71. DrawText(NewTwistTextDrawer(fontSize, 15, 0.04), code)
  72. } else if times < 6 {
  73. captchaImage = captchaImage.DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
  74. DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(43), rn).
  75. DrawLine(NewBeeline(), RandDeepColor()).
  76. DrawText(NewTwistTextDrawer(fontSize, 14, 0.03), code).
  77. DrawBlur(NewGaussianBlur(), 2, 0.15)
  78. } else if times < 10 {
  79. captchaImage = captchaImage.DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
  80. DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(45), rn).
  81. DrawLine(NewBeeline(), RandDeepColor()).
  82. DrawText(NewTwistTextDrawer(fontSize, 18, 0.04), code).
  83. DrawLine(NewBeeline(), RandDeepColor()).
  84. DrawBlur(NewGaussianBlur(), 2, 0.41)
  85. } else {
  86. captchaImage = captchaImage.DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(50), rn).
  87. DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
  88. DrawLine(NewBezier3DLine(), RandLightColor(rn)).
  89. DrawLine(NewBeeline(), RandDeepColor()).
  90. DrawText(NewTwistTextDrawer(fontSize, 18, 0.04), code).
  91. DrawBlur(NewGaussianBlur(), 2, 0.44)
  92. }
  93. if captchaImage.Error != nil {
  94. log.Println(captchaImage.Error)
  95. return
  96. }
  97. if times == 0 {
  98. ttl = 24 * 60 * 60
  99. }
  100. //计次
  101. times++
  102. globalStore.Set(code, RandomDigits(len([]rune(code))))
  103. //b := VerifyString(code, code)
  104. //fmt.Println(b)
  105. redis.Put("other", cacheKey, times, int(ttl))
  106. sess.Set(checkCode, code)
  107. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  108. w.Header().Set("Pragma", "no-cache")
  109. w.Header().Set("Expires", "0")
  110. w.Header().Set("Content-Type", "image/png")
  111. _ = captchaImage.Encode(w, ImageFormatJpeg)
  112. }