知识一:如何返回一个json数据?
先定义一个结构体ResponseData,2个参数,并返回的是json数据,key就是json后定义的名称
type ResponseData struct {
Status bool `json:"status"`
Message string `json:"message"`
}
再定义一个函数,返回结构体的指针。【也就是初始化了一个类,把对象返回一个对象。】
func NewJsondata() *ResponseData {
return &ResponseData{}
}
使用方法
result := NewJsondata() // 初始化,返回指针
result.Status = true // 赋值,和类赋值相同
result.Message = "验证成功"
知识二:如何定义一个全局变量?
在函数外定义的都是全局变量
var RegisterCode map[string] int64 = make(map[string] int64)
知识三:如何获取当前时间戳?
t := time.Now()
td := t.Unix()
知识四:map的操作 增加、循环、删除?
RegisterCode["name"] =“HaiRui” //增加值
for k :=range RegisterCode{ //循环
oldtt := RegisterCode[k] //根据key获取值
if td - oldtt > 300 { //条件判断
delete(RegisterCode,k); // 删除值
}
}
全部代码【海瑞博客】:
package main import ( crand "crypto/rand" "fmt" "image" "image/color" "image/png" "io" "math/rand" "net/http" "strconv" "time" "encoding/json" ) const ( stdWidth = 100 stdHeight = 40 maxSkew = 2 ) const ( fontWidth = 5 fontHeight = 8 blackChar = 1 ) type Validate_Data struct { code string tt int64 } type ResponseData struct { Status bool `json:"status"` Message string `json:"message"` } func NewJsondata() *ResponseData { return &ResponseData{} } var RegisterCode map[string] int64 = make(map[string] int64) var font = [][]byte{ { // 0 0, 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}, { // 1 0, 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}, { // 2 0, 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}, { // 3 1, 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}, { // 4 1, 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}, { // 5 1, 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}, { // 6 0, 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}, { // 7 1, 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}, { // 8 0, 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}, { // 9 0, 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.NRGBA color *color.NRGBA width int //a digit width height int //a digit height dotsize 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.dotsize maxy := height - img.height - img.dotsize*2 x := 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 int if width > height { border = height / 5 } else { border = width / 5 } // Convert everything to floats for calculations. w := float64(width - border*2) //268 h := float64(height - border*2) //48 // fw takes into account 1-dot spacing between digits. fw := float64(fontWidth) + 1 //6 fh := float64(fontHeight) //8 nc := 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 = 44 nw = 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.color maxx := img.Bounds().Max.X maxy := img.Bounds().Max.Y for 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 - radius dfx := 1 dfy := -2 * radius xx := 0 yy := radius img.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 += 2 f += dfy } xx++ dfx += 2 f += dfx img.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 := 0 maxx := img.Bounds().Max.X maxy := img.Bounds().Max.Y y := 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 radius maxr := img.dotsize/2 + img.dotsize/4 // maximum radius y += 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 += skf x = 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 = x if y < o { o = y } if z < o { o = z } return } func max3(x, y, z uint8) (o uint8) { o = x if 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 := 0 for { 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 := "" t := time.Now() td := t.Unix() // 清除超时验证码 for k :=range RegisterCode{ oldtt := RegisterCode[k] if td - oldtt > 300 { delete(RegisterCode,k); } } d = []byte(s) for v := range d { d[v] %= 10 ss += strconv.FormatInt(int64(d[v]), 32) } RegisterCode[ss] = td w.Header().Set("Content-Type", "image/png") NewImage(d, 100, 40).WriteTo(w) fmt.Println("验证码",ss,RegisterCode) } func validate(w http.ResponseWriter, req *http.Request) { code := req.FormValue("code") //取值 result := NewJsondata() if code == ""{ result.Status = false result.Message = "请输入验证码" }else { t := time.Now() td := t.Unix() // 处理超时的数据 for k :=range RegisterCode{ oldtt := RegisterCode[k] println(td,oldtt,td - oldtt) if td - oldtt > 300 { delete(RegisterCode,k); } } _, status := RegisterCode[code] if status{ result.Status = true result.Message = "验证成功" delete(RegisterCode,code); }else { result.Status = false result.Message = "验证码不正确" } } // 返回数据 bytes, _ := json.Marshal(result) fmt.Fprint(w, string(bytes)) } func main() { http.HandleFunc("/register/pic", pic) http.HandleFunc("/register/validate", validate) s := &http.Server{ Addr: ":8080", ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, MaxHeaderBytes: 1 << 20} s.ListenAndServe() }