123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- package gocaptcha
- import (
- "app.yhyue.com/moapp/jybase/go-xweb/httpsession"
- "app.yhyue.com/moapp/jybase/redis"
- "fmt"
- "image/color"
- "log"
- "math/rand"
- "net/http"
- "time"
- )
- // 图形验证码大小
- const (
- dx = 200
- dy = 80
- fontSize = 75
- Rn = 1
- CollectNum = 100
- Expiration = 10 * time.Minute
- )
- // 生成的字符集
- var (
- TextCharacters = []rune("ACDEFGHJKLMNPQRSTUVWXY2456789")
- globalStore = NewMemoryStore(CollectNum, Expiration)
- )
- // 初始化字体文件
- func InitCaptcha() {
- err := SetFontPath("./fonts/")
- if err != nil {
- log.Println(err)
- }
- }
- // RandText 生成随机字体.
- func RandText(num int) string {
- textNum := len(TextCharacters)
- text := make([]rune, num)
- for i := 0; i < num; i++ {
- text[i] = TextCharacters[rand.Intn(textNum)]
- }
- return string(text)
- }
- // RandLightColor 随机生成浅色底色.
- func RandLightColor(n int) color.RGBA {
- // 为每个颜色分量生成一个128到255之间的随机数
- red := rand.Intn(100/n) + 156 + (100 - 100/n)
- green := rand.Intn(100/n) + 156 + (100 - 100/n)
- blue := rand.Intn(100/n) + 156 + (100 - 100/n)
- // Alpha 通道设置为完全不透明
- a := uint8(rand.Intn(8) + 247)
- return color.RGBA{R: uint8(red), G: uint8(green), B: uint8(blue), A: a}
- }
- func Get(sess *httpsession.Session, checkCode string, w http.ResponseWriter, r *http.Request) {
- code := RandText(4)
- log.Println(code)
- cacheKey := fmt.Sprintf("captcha_times_%s", sess.Id())
- var (
- // 计次数
- times = redis.GetInt("other", cacheKey)
- ttl = redis.GetTTL("other", cacheKey)
- rn = times%6 + 1
- //跳色
- cc = RandLightColor(rn) //
- )
- // cc.A = uint8(rand.Intn(10) + 245)
- captchaImage := New(dx, dy, cc).
- DrawBorder(RandDeepColor())
- if times < 3 {
- captchaImage = captchaImage.DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
- DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(42), rn).
- DrawLine(NewBeeline(), RandDeepColor()).
- DrawText(NewTwistTextDrawer(fontSize, 15, 0.04), code)
- } else if times < 6 {
- captchaImage = captchaImage.DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
- DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(43), rn).
- DrawLine(NewBeeline(), RandDeepColor()).
- DrawText(NewTwistTextDrawer(fontSize, 14, 0.03), code).
- DrawBlur(NewGaussianBlur(), 2, 0.15)
- } else if times < 10 {
- captchaImage = captchaImage.DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
- DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(45), rn).
- DrawLine(NewBeeline(), RandDeepColor()).
- DrawText(NewTwistTextDrawer(fontSize, 18, 0.04), code).
- DrawLine(NewBeeline(), RandDeepColor()).
- DrawBlur(NewGaussianBlur(), 2, 0.41)
- } else {
- captchaImage = captchaImage.DrawNoise(NoiseDensityHigh, NewTextNoiseDrawer(50), rn).
- DrawNoise(NoiseDensityLower, NewPointNoiseDrawer(), rn).
- DrawLine(NewBezier3DLine(), RandLightColor(rn)).
- DrawLine(NewBeeline(), RandDeepColor()).
- DrawText(NewTwistTextDrawer(fontSize, 18, 0.04), code).
- DrawBlur(NewGaussianBlur(), 2, 0.44)
- }
- if captchaImage.Error != nil {
- log.Println(captchaImage.Error)
- return
- }
- if times == 0 {
- ttl = 24 * 60 * 60
- }
- //计次
- times++
- globalStore.Set(code, RandomDigits(len([]rune(code))))
- //b := VerifyString(code, code)
- //fmt.Println(b)
- redis.Put("other", cacheKey, times, int(ttl))
- sess.Set(checkCode, code)
- w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
- w.Header().Set("Pragma", "no-cache")
- w.Header().Set("Expires", "0")
- w.Header().Set("Content-Type", "image/png")
- _ = captchaImage.Encode(w, ImageFormatJpeg)
- }
|