goCaptcha/captcha.go
captcha.goRaw
1package main
2
3import (
4 "fmt"
5 "math/rand"
6 "os/exec"
7 "strings"
8 "time"
9
10 "gopkg.in/mgo.v2/bson"
11)
12
13type Captcha struct {
14 Id string `json:"id"`
15 Imgs []string `json:"imgs"`
16 Question string `json:"question"`
17 Date string `json:"date"`
18}
19type CaptchaSol struct {
20 Id string `json:"id"`
21 ImgsSolution []string `json:"imgssolution"`
22 Question string `json:"question"` //select all X
23 Date int64 `json:"date"`
24 Ip string `json:"ip"`
25}
26type CaptchaAnswer struct {
27 CaptchaId string `json:"captchaid"`
28 Selection []int `json:"selection"`
29}
30type ImgFakePath struct {
31 CaptchaId string `json:"captchaid"`
32 Real string `json:"real"`
33 Fake string `json:"fake"`
34}
35
36func generateUUID() string {
37 out, err := exec.Command("uuidgen").Output()
38 check(err)
39 uuid := string(out)
40 uuid = strings.Replace(uuid, "\n", "", -1)
41 return uuid
42}
43func generateRandInt(min int, max int) int {
44 //rand.Seed(time.Now().UTC().UnixNano())
45 return rand.Intn(max-min) + min
46}
47func generateQuestionFromCategoriesArray(imgs []string) string {
48 n := generateRandInt(0, len(imgs))
49 return imgs[n]
50}
51func generateCaptcha(count int, ip string) Captcha {
52 var captcha Captcha
53 var captchaSol CaptchaSol
54
55 captcha.Id = generateUUID()
56 captchaSol.Id = captcha.Id
57
58 for i := 0; i < count; i++ {
59 nCateg := generateRandInt(0, len(categDataset))
60 nImg := generateRandInt(0, len(dataset[categDataset[nCateg]]))
61 //imgFakePath
62 var imgFakePath ImgFakePath
63 imgFakePath.CaptchaId = captcha.Id
64 imgFakePath.Real = categDataset[nCateg] + "/" + dataset[categDataset[nCateg]][nImg]
65 imgFakePath.Fake = generateUUID() + ".png"
66 err := imgFakePathCollection.Insert(imgFakePath)
67 check(err)
68 captcha.Imgs = append(captcha.Imgs, imgFakePath.Fake)
69 captchaSol.ImgsSolution = append(captchaSol.ImgsSolution, categDataset[nCateg])
70 }
71 question := generateQuestionFromCategoriesArray(captchaSol.ImgsSolution)
72 captcha.Question = question
73 captchaSol.Question = question
74 captchaSol.Date = time.Now().Unix()
75 captchaSol.Ip = ip
76 err := captchaSolCollection.Insert(captchaSol)
77 check(err)
78 return captcha
79}
80func validateCaptcha(captchaAnswer CaptchaAnswer, ip string) bool {
81 var solved bool
82 solved = true
83 captchaSol := CaptchaSol{}
84 err := captchaSolCollection.Find(bson.M{"id": captchaAnswer.CaptchaId}).One(&captchaSol)
85 check(err)
86 for k, imgSol := range captchaSol.ImgsSolution {
87 if imgSol == captchaSol.Question {
88 if captchaAnswer.Selection[k] == 1 {
89 //correct
90 } else {
91 solved = false
92 }
93 }
94 if imgSol != captchaSol.Question {
95 if captchaAnswer.Selection[k] == 0 {
96 //correct
97 } else {
98 solved = false
99 }
100 }
101 }
102
103 //time elapsed from captcha generation comprovation
104 date := time.Unix(captchaSol.Date, 0)
105 elapsed := time.Since(date)
106 fmt.Println(elapsed.Seconds())
107 if elapsed.Seconds() < 1 {
108 solved = false
109 }
110 if elapsed.Seconds() > 60 {
111 solved = false
112 }
113 //ip comprovation
114 if captchaSol.Ip != ip {
115 solved = false
116 }
117 return solved
118}