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
- golang(beego)验证码控制器
- golang(beego) 发送邮件
- Centos 安装golang beego
- golang、beego初探
- golang-beego的使用
- golang: beego自动化部署
- [golang]beego列表分页
- GOLANG BEEGO ORM
- GoLang缩略图+beego项目
- beego 验证码,含详细代码
- 搭建golang的beego注意事项
- golang beego框架使用有感
- golang beego 路由个人理解
- golang 图片验证码
- golang(2):beego 环境搭建
- linux安装golang 以及beego框架
- ubnutu下golang安装Beego框架
- golang web框架 配置文件读取 借鉴 beego
- 学习方法
- 关于Hibernate
- android中选择控件与选择界面自然过度效果的实现--一种新的交互设计
- 校园双选会,你都懂么
- 数据结构线性表f
- golang(beego)验证码控制器
- paint画笔
- PS 常用快捷键
- LSM树由来、设计思想以及应用到HBase的索引
- 常用算法之交换两个数的值
- 【Leetcode】Path Sum (Sum)
- 从Red5的win版本安装到简单的hello world例子
- 在Android下操作Excel
- 使用 MYSQLBINLOG 来恢复数据