golang(beego)验证码控制器

来源:互联网 发布:jquery 表单数据验证 编辑:程序博客网 时间:2024/05/16 08:19

核心代码是封装的别人的

代码如下:

/** * 用法 *1)注册一下路由 *  beego.Router("/yzm", &controllers.YzmController{}, "Get:GetYzm")             //验证码控制器 *beego.Router("/yzm/judgeyzm", &controllers.YzmController{}, "Post:JudgeYzm") //验证码ajax验证 * * 2)用法 *  <img src="/yzm" onclick="this.src='/yzm?'+Math.random()" > */package controllersimport (crand "crypto/rand"// "fmt""github.com/astaxie/beego""github.com/astaxie/beego/session""image""image/color""image/png""io""math/rand""net/http""strconv""time")var globalSessions *session.Managerfunc init() {globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid", "enableSetCookie,omitempty": true, "gclifetime":3600, "maxLifetime": 3600, "secure": false, "sessionIDHashFunc": "sha1", "sessionIDHashKey": "", "cookieLifeTime": 3600, "providerConfig": ""}`)go globalSessions.GC()}type YzmController struct {beego.Controller}/** * 获取验证码 */func (this *YzmController) GetYzm() {pic(this.Ctx.ResponseWriter, this.Ctx.Request)}/** * ajax判断验证码 */func (this *YzmController) JudgeYzm() {p := this.GetString("param")rs := "对不起,输入" + p + "为错误!"sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)if sess.Get("yzm") == p {rs = "y" //返回y表示正确}this.Ctx.WriteString(rs)}const (stdWidth  = 100stdHeight = 40maxSkew   = 2)const (fontWidth  = 5fontHeight = 8blackChar  = 1)var font = [][]byte{{ // 00, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,0, 1, 1, 1, 0,},{ // 10, 0, 1, 0, 0,0, 1, 1, 0, 0,1, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,1, 1, 1, 1, 1,},{ // 20, 1, 1, 1, 0,1, 0, 0, 0, 1,0, 0, 0, 0, 1,0, 0, 0, 1, 1,0, 1, 1, 0, 0,1, 0, 0, 0, 0,1, 0, 0, 0, 0,1, 1, 1, 1, 1,},{ // 31, 1, 1, 1, 0,0, 0, 0, 0, 1,0, 0, 0, 1, 0,0, 1, 1, 1, 0,0, 0, 0, 1, 0,0, 0, 0, 0, 1,0, 0, 0, 0, 1,1, 1, 1, 1, 0,},{ // 41, 0, 0, 1, 0,1, 0, 0, 1, 0,1, 0, 0, 1, 0,1, 0, 0, 1, 0,1, 1, 1, 1, 1,0, 0, 0, 1, 0,0, 0, 0, 1, 0,0, 0, 0, 1, 0,},{ // 51, 1, 1, 1, 1,1, 0, 0, 0, 0,1, 0, 0, 0, 0,1, 1, 1, 1, 0,0, 0, 0, 0, 1,0, 0, 0, 0, 1,0, 0, 0, 0, 1,1, 1, 1, 1, 0,},{ // 60, 0, 1, 1, 1,0, 1, 0, 0, 0,1, 0, 0, 0, 0,1, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,0, 1, 1, 1, 0,},{ // 71, 1, 1, 1, 1,0, 0, 0, 0, 1,0, 0, 0, 0, 1,0, 0, 0, 1, 0,0, 0, 1, 0, 0,0, 1, 0, 0, 0,0, 1, 0, 0, 0,0, 1, 0, 0, 0,},{ // 80, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,0, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,0, 1, 1, 1, 0,},{ // 90, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 1, 0, 0, 1,0, 1, 1, 1, 1,0, 0, 0, 0, 1,0, 0, 0, 0, 1,1, 1, 1, 1, 0,},}type Image struct {*image.NRGBAcolor   *color.NRGBAwidth   int //a digit widthheight  int //a digit heightdotsize int}func init() {rand.Seed(int64(time.Second))}func NewImage(digits []byte, width, height int) *Image {img := new(Image)r := image.Rect(img.width, img.height, stdWidth, stdHeight)img.NRGBA = image.NewNRGBA(r)img.color = &color.NRGBA{uint8(rand.Intn(129)),uint8(rand.Intn(129)),uint8(rand.Intn(129)),0xFF,}// Draw background (10 random circles of random brightness)img.calculateSizes(width, height, len(digits))img.fillWithCircles(10, img.dotsize)maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsizemaxy := height - img.height - img.dotsize*2x := rnd(img.dotsize*2, maxx)y := rnd(img.dotsize*2, maxy)// Draw digits.for _, n := range digits {img.drawDigit(font[n], x, y)x += img.width + img.dotsize}// Draw strike-through line.img.strikeThrough()return img}func (img *Image) WriteTo(w io.Writer) (int64, error) {return 0, png.Encode(w, img)}func (img *Image) calculateSizes(width, height, ncount int) {// Goal: fit all digits inside the image.var border intif width > height {border = height / 5} else {border = width / 5}// Convert everything to floats for calculations.w := float64(width - border*2)  //268h := float64(height - border*2) //48// fw takes into account 1-dot spacing between digits.fw := float64(fontWidth) + 1 //6fh := float64(fontHeight) //8nc := float64(ncount)     //7// Calculate the width of a single digit taking into account only the// width of the image.nw := w / nc //38// Calculate the height of a digit from this width.nh := nw * fh / fw //51// Digit too high?if nh > h {// Fit digits based on height.nh = h //nh = 44nw = fw / fh * nh}// Calculate dot size.img.dotsize = int(nh / fh)// Save everything, making the actual width smaller by 1 dot to account// for spacing between digits.img.width = int(nw)img.height = int(nh) - img.dotsize}func (img *Image) fillWithCircles(n, maxradius int) {color := img.colormaxx := img.Bounds().Max.Xmaxy := img.Bounds().Max.Yfor i := 0; i < n; i++ {setRandomBrightness(color, 255)r := rnd(1, maxradius)img.drawCircle(color, rnd(r, maxx-r), rnd(r, maxy-r), r)}}func (img *Image) drawHorizLine(color color.Color, fromX, toX, y int) {for x := fromX; x <= toX; x++ {img.Set(x, y, color)}}func (img *Image) drawCircle(color color.Color, x, y, radius int) {f := 1 - radiusdfx := 1dfy := -2 * radiusxx := 0yy := radiusimg.Set(x, y+radius, color)img.Set(x, y-radius, color)img.drawHorizLine(color, x-radius, x+radius, y)for xx < yy {if f >= 0 {yy--dfy += 2f += dfy}xx++dfx += 2f += dfximg.drawHorizLine(color, x-xx, x+xx, y+yy)img.drawHorizLine(color, x-xx, x+xx, y-yy)img.drawHorizLine(color, x-yy, x+yy, y+xx)img.drawHorizLine(color, x-yy, x+yy, y-xx)}}func (img *Image) strikeThrough() {r := 0maxx := img.Bounds().Max.Xmaxy := img.Bounds().Max.Yy := rnd(maxy/3, maxy-maxy/3)for x := 0; x < maxx; x += r {r = rnd(1, img.dotsize/3)y += rnd(-img.dotsize/2, img.dotsize/2)if y <= 0 || y >= maxy {y = rnd(maxy/3, maxy-maxy/3)}img.drawCircle(img.color, x, y, r)}}func (img *Image) drawDigit(digit []byte, x, y int) {skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew))xs := float64(x)minr := img.dotsize / 2               // minumum radiusmaxr := img.dotsize/2 + img.dotsize/4 // maximum radiusy += rnd(-minr, minr)for yy := 0; yy < fontHeight; yy++ {for xx := 0; xx < fontWidth; xx++ {if digit[yy*fontWidth+xx] != blackChar {continue}// 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.color, ox, oy, or)}xs += skfx = int(xs)}}func setRandomBrightness(c *color.NRGBA, max uint8) {minc := min3(c.R, c.G, c.B)maxc := max3(c.R, c.G, c.B)if maxc > max {return}n := rand.Intn(int(max-maxc)) - int(minc)c.R = uint8(int(c.R) + n)c.G = uint8(int(c.G) + n)c.B = uint8(int(c.B) + n)}func min3(x, y, z uint8) (o uint8) {o = xif y < o {o = y}if z < o {o = z}return}func max3(x, y, z uint8) (o uint8) {o = xif y > o {o = y}if z > o {o = z}return}// rnd returns a random number in range [from, to].func rnd(from, to int) int {//println(to+1-from)return rand.Intn(to+1-from) + from}const (// Standard length of uniuri string to achive ~95 bits of entropy.StdLen = 16// Length of uniurl string to achive ~119 bits of entropy, closest// to what can be losslessly converted to UUIDv4 (122 bits).UUIDLen = 20)// Standard characters allowed in uniuri string.var StdChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")// New returns a new random string of the standard length, consisting of// standard characters.func New() string {return NewLenChars(StdLen, StdChars)}// NewLen returns a new random string of the provided length, consisting of// standard characters.func NewLen(length int) string {return NewLenChars(length, StdChars)}// NewLenChars returns a new random string of the provided length, consisting// of the provided byte slice of allowed characters (maximum 256).func NewLenChars(length int, chars []byte) string {b := make([]byte, length)r := make([]byte, length+(length/4)) // storage for random bytes.clen := byte(len(chars))maxrb := byte(256 - (256 % len(chars)))i := 0for {if _, err := io.ReadFull(crand.Reader, r); err != nil {panic("error reading from random source: " + err.Error())}for _, c := range r {if c >= maxrb {// Skip this number to avoid modulo bias.continue}b[i] = chars[c%clen]i++if i == length {return string(b)}}}panic("unreachable")}func pic(w http.ResponseWriter, req *http.Request) {d := make([]byte, 4)s := NewLen(4)ss := ""d = []byte(s)for v := range d {d[v] %= 10ss += strconv.FormatInt(int64(d[v]), 32)}w.Header().Set("Content-Type", "image/png")sess := globalSessions.SessionStart(w, req)defer sess.SessionRelease(w)sess.Delete("yzm")sess.Set("yzm", ss)//fmt.Println("-----------------------------------yzm:", sess.Get("yzm"))NewImage(d, 100, 40).WriteTo(w)}func index(w http.ResponseWriter, req *http.Request) {str := "<meta charset=\"utf-8\"><h3>golang 图片验证码例子</h3><img border=\"1\" src=\"/pic\" alt=\"图片验证码\" onclick=\"this.src='/pic'\" />"w.Header().Set("Content-Type", "text/html")w.Write([]byte(str))}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 十一个月宝宝断奶不喝奶粉怎么办 孩子三门成绩全不及格家长该怎么办 宝宝快十个月了还不会爬怎么办 小孩写字老把手向里扭曲怎么办 孩子该上四年级了数学差的很怎么办 孩子上三年级了数学成绩好差怎么办 三年级数学老考70-80分怎么办 叛逆期的孩子用死来威胁家长怎么办 叛逆期的孩子抽烟喝酒家长该怎么办 大学遇到不好的老师加课怎么办 两岁的宝宝脾气古怪不听话怎么办 16个月宝宝不听话脾气大怎么办 如果你很害怕去面对一件事怎么办 孩子上幼儿园哭老师不理孩子怎么办 发现幼儿园给孩子吃药片该怎么办 做老师的打学生被家长投诉怎么办 学生认为老师向家长打报告怎么办 老师发打12分的试卷给家长怎么办 孩子在学校顶撞老师不让上学怎么办 被老师骂了不敢去学校怎么办 孩子不爱去幼儿园 总是哭怎么办呢 孩子在幼儿园被老师罚家长该怎么办 孩子不喜欢幼儿园里的体能课怎么办 初中叛逆期的孩子怎么办老师做法 二年级孩子不受老师待见怎么办 孩子该上初中了没学籍怎么办 四个多月的婴儿不喜欢看人怎么办 2个月婴儿不喜欢吃奶粉怎么办 想学习但是又学不进去怎么办 在省外读书 回来读高中学籍怎么办 一岁宝宝这几天不爱吃饭怎么办 2岁的宝宝吃多了怎么办 小孩吃了退烧药吐了怎么办 牙齿与牙齿之间有洞喜欢塞牙怎么办 胃有点烧心天天没食欲不饿怎么办 1岁半宝宝不吃饭光喝奶粉怎么办 一岁半宝宝光喝奶粉不吃饭怎么办 一岁半的宝宝光喝奶粉不吃饭怎么办 两岁半宝宝光喝奶粉不吃饭怎么办 宝宝9个月不好好吃饭奶粉怎么办 2岁半宝宝不愿意自己吃饭怎么办