1、http://www.oschina.net/code/snippet_173630_12006

效果:

Go 语言做的几个验证码 Go 语言做的几个验证码

Go 语言做的几个验证码 Go 语言做的几个验证码 Go 语言做的几个验证码

源代码:

1: package main
   2:  
   3: import (
  14: )
  15:  
const (
  17:     stdWidth  = 100
  18:     stdHeight = 40
  19:     maxSkew   = 2
  20: )
  21:  
const (
  23:     fontWidth  = 5
  24:     fontHeight = 8
  25:     blackChar  = 1
  26: )
  27:  
  28: var font = [][]byte{
// 0
  30:         0, 1, 1, 1, 0,
  31:         1, 0, 0, 0, 1,
  32:         1, 0, 0, 0, 1,
  33:         1, 0, 0, 0, 1,
  34:         1, 0, 0, 0, 1,
  35:         1, 0, 0, 0, 1,
  36:         1, 0, 0, 0, 1,
  37:         0, 1, 1, 1, 0},
// 1
  39:         0, 0, 1, 0, 0,
  40:         0, 1, 1, 0, 0,
  41:         1, 0, 1, 0, 0,
  42:         0, 0, 1, 0, 0,
  43:         0, 0, 1, 0, 0,
  44:         0, 0, 1, 0, 0,
  45:         0, 0, 1, 0, 0,
  46:         1, 1, 1, 1, 1},
// 2
  48:         0, 1, 1, 1, 0,
  49:         1, 0, 0, 0, 1,
  50:         0, 0, 0, 0, 1,
  51:         0, 0, 0, 1, 1,
  52:         0, 1, 1, 0, 0,
  53:         1, 0, 0, 0, 0,
  54:         1, 0, 0, 0, 0,
  55:         1, 1, 1, 1, 1},
// 3
  57:         1, 1, 1, 1, 0,
  58:         0, 0, 0, 0, 1,
  59:         0, 0, 0, 1, 0,
  60:         0, 1, 1, 1, 0,
  61:         0, 0, 0, 1, 0,
  62:         0, 0, 0, 0, 1,
  63:         0, 0, 0, 0, 1,
  64:         1, 1, 1, 1, 0},
// 4
  66:         1, 0, 0, 1, 0,
  67:         1, 0, 0, 1, 0,
  68:         1, 0, 0, 1, 0,
  69:         1, 0, 0, 1, 0,
  70:         1, 1, 1, 1, 1,
  71:         0, 0, 0, 1, 0,
  72:         0, 0, 0, 1, 0,
  73:         0, 0, 0, 1, 0},
// 5
  75:         1, 1, 1, 1, 1,
  76:         1, 0, 0, 0, 0,
  77:         1, 0, 0, 0, 0,
  78:         1, 1, 1, 1, 0,
  79:         0, 0, 0, 0, 1,
  80:         0, 0, 0, 0, 1,
  81:         0, 0, 0, 0, 1,
  82:         1, 1, 1, 1, 0},
// 6
  84:         0, 0, 1, 1, 1,
  85:         0, 1, 0, 0, 0,
  86:         1, 0, 0, 0, 0,
  87:         1, 1, 1, 1, 0,
  88:         1, 0, 0, 0, 1,
  89:         1, 0, 0, 0, 1,
  90:         1, 0, 0, 0, 1,
  91:         0, 1, 1, 1, 0},
// 7
  93:         1, 1, 1, 1, 1,
  94:         0, 0, 0, 0, 1,
  95:         0, 0, 0, 0, 1,
  96:         0, 0, 0, 1, 0,
  97:         0, 0, 1, 0, 0,
  98:         0, 1, 0, 0, 0,
  99:         0, 1, 0, 0, 0,
 100:         0, 1, 0, 0, 0},
// 8
 102:         0, 1, 1, 1, 0,
 103:         1, 0, 0, 0, 1,
 104:         1, 0, 0, 0, 1,
 105:         0, 1, 1, 1, 0,
 106:         1, 0, 0, 0, 1,
 107:         1, 0, 0, 0, 1,
 108:         1, 0, 0, 0, 1,
 109:         0, 1, 1, 1, 0},
// 9
 111:         0, 1, 1, 1, 0,
 112:         1, 0, 0, 0, 1,
 113:         1, 0, 0, 0, 1,
 114:         1, 1, 0, 0, 1,
 115:         0, 1, 1, 1, 1,
 116:         0, 0, 0, 0, 1,
 117:         0, 0, 0, 0, 1,
 118:         1, 1, 1, 1, 0},
 119: }
 120:  
struct {
 122:     *image.NRGBA
 123:     color   *color.NRGBA
//a digit width
//a digit height
int
 127: }
 128:  
 129: func init() {
 130:     rand.Seed(int64(time.Second))
 131:  
 132: }
 133:  
int) *Image {
new(Image)
 136:     r := image.Rect(img.width, img.height, stdWidth, stdHeight)
 137:     img.NRGBA = image.NewNRGBA(r)
 138:     img.color = &color.NRGBA{
 139:         uint8(rand.Intn(129)),
 140:         uint8(rand.Intn(129)),
 141:         uint8(rand.Intn(129)),
 142:         0xFF}
// Draw background (10 random circles of random brightness)
 144:     img.calculateSizes(width, height, len(digits))
 145:     img.fillWithCircles(10, img.dotsize)
 146:     maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsize
 147:     maxy := height - img.height - img.dotsize*2
 148:     x := rnd(img.dotsize*2, maxx)
 149:     y := rnd(img.dotsize*2, maxy)
// Draw digits.
for _, n := range digits {
 152:         img.drawDigit(font[n], x, y)
 153:         x += img.width + img.dotsize
 154:     }
// Draw strike-through line.
 156:     img.strikeThrough()
return img
 158:  
 159: }
 160:  
 161: func (img *Image) WriteTo(w io.Writer) (int64, error) {
return 0, png.Encode(w, img)
 163:  
 164: }
 165:  
int) {
// Goal: fit all digits inside the image.
int
if width > height {
 170:         border = height / 5
else {
 172:         border = width / 5
 173:     }
// Convert everything to floats for calculations.
//268
//48
// fw takes into account 1-dot spacing between digits.
//6
//8
//7
// Calculate the width of a single digit taking into account only the
// width of the image.
//38
// Calculate the height of a digit from this width.
//51
// Digit too high?
if nh > h {
// Fit digits based on height.
//nh = 44
 190:         nw = fw / fh * nh
 191:     }
// Calculate dot size.
int(nh / fh)
// Save everything, making the actual width smaller by 1 dot to account
// for spacing between digits.
int(nw)
int(nh) - img.dotsize
 198:  
 199: }
 200:  
int) {
 202:     color := img.color
 203:     maxx := img.Bounds().Max.X
 204:     maxy := img.Bounds().Max.Y
for i := 0; i < n; i++ {
 206:         setRandomBrightness(color, 255)
 207:         r := rnd(1, maxradius)
 208:         img.drawCircle(color, rnd(r, maxx-r), rnd(r, maxy-r), r)
 209:     }
 210:  
 211: }
 212:  
int) {
for x := fromX; x <= toX; x++ {
 215:         img.Set(x, y, color)
 216:     }
 217:  
 218: }
 219:  
int) {
 221:     f := 1 - radius
 222:     dfx := 1
 223:     dfy := -2 * radius
 224:     xx := 0
 225:     yy := radius
 226:     img.Set(x, y+radius, color)
 227:     img.Set(x, y-radius, color)
 228:     img.drawHorizLine(color, x-radius, x+radius, y)
for xx < yy {
if f >= 0 {
 231:             yy--
 232:             dfy += 2
 233:             f += dfy
 234:         }
 235:         xx++
 236:         dfx += 2
 237:         f += dfx
 238:         img.drawHorizLine(color, x-xx, x+xx, y+yy)
 239:         img.drawHorizLine(color, x-xx, x+xx, y-yy)
 240:         img.drawHorizLine(color, x-yy, x+yy, y+xx)
 241:         img.drawHorizLine(color, x-yy, x+yy, y-xx)
 242:     }
 243:  
 244: }
 245:  
 246: func (img *Image) strikeThrough() {
 247:     r := 0
 248:     maxx := img.Bounds().Max.X
 249:     maxy := img.Bounds().Max.Y
 250:     y := rnd(maxy/3, maxy-maxy/3)
for x := 0; x < maxx; x += r {
 252:         r = rnd(1, img.dotsize/3)
 253:         y += rnd(-img.dotsize/2, img.dotsize/2)
if y <= 0 || y >= maxy {
 255:             y = rnd(maxy/3, maxy-maxy/3)
 256:         }
 257:         img.drawCircle(img.color, x, y, r)
 258:     }
 259:  
 260: }
 261:  
int) {
 263:     skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew))
 264:     xs := float64(x)
// minumum radius
// maximum radius
 267:     y += rnd(-minr, minr)
for yy := 0; yy < fontHeight; yy++ {
for xx := 0; xx < fontWidth; xx++ {
if digit[yy*fontWidth+xx] != blackChar {
continue
 272:             }
// Introduce random variations.
 274:             or := rnd(minr, maxr)
 275:             ox := x + (xx * img.dotsize) + rnd(0, or/2)
 276:             oy := y + (yy * img.dotsize) + rnd(0, or/2)
 277:             img.drawCircle(img.color, ox, oy, or)
 278:         }
 279:         xs += skf
int(xs)
 281:     }
 282:  
 283: }
 284:  
 285: func setRandomBrightness(c *color.NRGBA, max uint8) {
 286:     minc := min3(c.R, c.G, c.B)
 287:     maxc := max3(c.R, c.G, c.B)
if maxc > max {
return
 290:     }
int(minc)
int(c.R) + n)
int(c.G) + n)
int(c.B) + n)
 295:  
 296: }
 297:  
 298: func min3(x, y, z uint8) (o uint8) {
 299:     o = x
if y < o {
 301:         o = y
 302:     }
if z < o {
 304:         o = z
 305:     }
return
 307:  
 308: }
 309:  
 310: func max3(x, y, z uint8) (o uint8) {
 311:     o = x
if y > o {
 313:         o = y
 314:     }
if z > o {
 316:         o = z
 317:     }
return
 319:  
 320: }
 321:  
// rnd returns a random number in range [from, to].
 323:  
int {
//println(to+1-from)
return rand.Intn(to+1-from) + from
 327:  
 328: }
 329:  
const (
// Standard length of uniuri string to achive ~95 bits of entropy.
 332:     StdLen = 16
// Length of uniurl string to achive ~119 bits of entropy, closest
// to what can be losslessly converted to UUIDv4 (122 bits).
 335:     UUIDLen = 20
 336: )
 337:  
// Standard characters allowed in uniuri string.
 339:  
)
 341:  
// New returns a new random string of the standard length, consisting of
// standard characters.
 344:  
 345: func New() string {
return NewLenChars(StdLen, StdChars)
 347:  
 348: }
 349:  
// NewLen returns a new random string of the provided length, consisting of
// standard characters.
 352:  
int) string {
return NewLenChars(length, StdChars)
 355:  
 356: }
 357:  
// NewLenChars returns a new random string of the provided length, consisting
// of the provided byte slice of allowed characters (maximum 256).
 360:  
int, chars []byte) string {
 362:     b := make([]byte, length)
// storage for random bytes.
 364:     clen := byte(len(chars))
 365:     maxrb := byte(256 - (256 % len(chars)))
 366:     i := 0
for {
if _, err := io.ReadFull(crand.Reader, r); err != nil {
 + err.Error())
 370:         }
for _, c := range r {
if c >= maxrb {
// Skip this number to avoid modulo bias.
continue
 375:             }
 376:             b[i] = chars[c%clen]
 377:             i++
if i == length {
return string(b)
 380:             }
 381:         }
 382:     }
)
 384:  
 385: }
 386:  
 387: func pic(w http.ResponseWriter, req *http.Request) {
 388:     d := make([]byte, 4)
 389:     s := NewLen(4)
 391:     d = []byte(s)
for v := range d {
 393:         d[v] %= 10
 394:         ss += strconv.FormatInt(int64(d[v]), 32)
 395:     }
)
 397:     NewImage(d, 100, 40).WriteTo(w)
 398:     fmt.Println(ss)
 399:  
 400: }
 401:  
 402: func index(w http.ResponseWriter, req *http.Request) {
)
 405:     w.Write([]byte(str))
 406:  
 407: }
 408:  
 409: func main() {
, pic)
, index)
 412:     s := &http.Server{
,
 414:         ReadTimeout:    30 * time.Second,
 415:         WriteTimeout:   30 * time.Second,
 416:         MaxHeaderBytes: 1 << 20}
 417:     s.ListenAndServe()
 418:  
 419: }

相关文章:

  • 2021-05-19
  • 2021-12-25
  • 2021-08-09
  • 2021-10-05
  • 2022-01-17
  • 2022-12-23
  • 2021-11-11
  • 2021-05-20
猜你喜欢
  • 2022-12-23
  • 2021-11-08
  • 2021-10-05
  • 2021-09-22
  • 2022-12-23
  • 2021-12-27
  • 2021-11-29
相关资源
相似解决方案