Let’s play the verification code with go

Time:2021-12-2

[TOC]

Let’s play the verification code with go

Hi, I’m the Little Devil boy Nezha. In the go we shared last timedeferLet’s review the implementation principle of

  • Shared what a defer is
  • A simple illustration of the stack and queue
  • Defer data structure and implementation principle, specific source code display
  • In godeferof3Rule

If in godeferIf you are still interested in the implementation principle, please check the implementation principle of defer in go

Today, let’s share some usageGOTo realize small cases, let’s grow while playing

Let's play the verification code with go

Go verification code introduction

The verification codes we usually use are roughly divided into these types. Let’s sort them out:

  • Traditional input form

Enter numbers, words, letters, etc. on the picture

  • Enter a graphic verification code for the type

This is mainly for advertising

  • Pure behavior verification code

For example, follow the prompts to slide, and so on

  • Icon selection and behavior assisted verification code

For example, when we buy train tickets, you can choose the verification code and various icons

  • Click and click graphic verification and behavior assistance

For example, the verification code of a treasure

  • Intelligent verification code

For example, touch the smart verification code

Go verification code case

Let’s play the first and most used verification code today

The verification code library of go will be used to complete it,github.com/dchest/captcha

If we askC/C++Similarly, it’s tiring for us to encapsulate and implement a lot of bottom processing ourselves. Go is really good. There are many packages used. In addition to using them, we can also stand on the shoulders of giants, learn the implementation methods in the source code and learn the design ideas of big guys.

Let's play the verification code with go

installcaptchalibrary

You can use the following command to download it

go get github.com/dchest/captcha

When we wereGOLANDUsed incaptchaLibrary, we can look at the source directory

Source directory

Let's play the verification code with go

  • Specific use cases with source code
  • Specific example pictures
  • Implementation of related audio processing
  • Implementation of verification code processing
  • Implementation of image processing
  • Implementation of random number processing
  • wait…

Supported languages

Let's play the verification code with go

The audio currently supported by this library are4Languages:

  • english
  • chinese
  • Russian
  • Japanese

Verification code default parameters

The size of the verification code in the library is by defaultWidth 240 Px, height 80 PX

In the source codeimage.go

const (
   // Standard width and height of a captcha image.
   StdWidth  = 240
   StdHeight = 80
   // Maximum absolute skew factor of a single digit.
   maxSkew = 0.7
   // Number of background circles.
   circleCount = 20
)

type Image struct {
   *image.Paletted
   numWidth  int
   numHeight int
   dotSize   int
   rng       siprng
}

Characters contained in random numbers

The following are the characters allowed in the verification code ID, which can be seen in the source code

In the source packagerandom.go

// idChars are characters allowed in captcha id.
var idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")

Audio processing

In the source codesounds.gofile

Currently, only audio is supported4Two languages,"en", "ja", "ru", "zh".

/ NewAudio returns a new audio captcha with the given digits, where each digit
// must be in range 0-9. Digits are pronounced in the given language. If there
// are no sounds for the given language, English is used.
//
// Possible values for lang are "en", "ja", "ru", "zh".
func NewAudio(id string, digits []byte, lang string) *Audio {
   a := new(Audio)

   // Initialize PRNG.
   a.rng.Seed(deriveSeed(audioSeedPurpose, id, digits))

   if sounds, ok := digitSounds[lang]; ok {
      a.digitSounds = sounds
   } else {
      a.digitSounds = digitSounds["en"]
   }
   numsnd := make([][]byte, len(digits))
   nsdur := 0
   for i, n := range digits {
      snd := a.randomizedDigitSound(n)
      nsdur += len(snd)
      numsnd[i] = snd
   }
   // Random intervals between digits (including beginning).
   intervals := make([]int, len(digits)+1)
   intdur := 0
   for i := range intervals {
      dur := a.rng.Int(sampleRate, sampleRate*3) // 1 to 3 seconds
      intdur += dur
      intervals[i] = dur
   }
   // Generate background sound.
   bg := a.makeBackgroundSound(a.longestDigitSndLen()*len(digits) + intdur)
   // Create buffer and write audio to it.
   sil := makeSilence(sampleRate / 5)
   bufcap := 3*len(beepSound) + 2*len(sil) + len(bg) + len(endingBeepSound)
   a.body = bytes.NewBuffer(make([]byte, 0, bufcap))
   // Write prelude, three beeps.
   a.body.Write(beepSound)
   a.body.Write(sil)
   a.body.Write(beepSound)
   a.body.Write(sil)
   a.body.Write(beepSound)
   // Write digits.
   pos := intervals[0]
   for i, v := range numsnd {
      mixSound(bg[pos:], v)
      pos += len(v) + intervals[i+1]
   }
   a.body.Write(bg)
   // Write ending (one beep).
   a.body.Write(endingBeepSound)
   return a
}

The data about language is indigitSoundsIn map

Seeing this is a bit like doing font analysis and embedded data analysis

Let's play the verification code with go

var digitSounds = map[string][][]byte{
    "en": [][]byte{
        { // 0
            0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80,
            ...
        },
    "ru": [][]byte{
        { // 0
             0x7f, 0x7f, 0x7e, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7f, 0x7e,
            ...
        },
    "zh": [][]byte{
        { // 0
            0x7f, 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80,
            ...
        },
    "ja": [][]byte{
        { // 0
             0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x83,
            ...
        }, 

Start the presentation of the case

Let's play the verification code with go

my_captcha.htmlThe implementation is as follows

For the time being, I’ll write about the audio language2Languages

  • english
  • chinese
<!doctype html>
<head>
    < title > go simple production verification code case < / Title >
    <style>
        input{
            margin-top: 30px;
        }
    </style>
</head>
<body>
<script>

    //Set language
    function setSrcQuery(e, q) {
        var src = e.src;
        var p = src.indexOf('?');
        if (p >= 0) {
            src = src.substr(0, p);
        }
        e.src = src + "?" + q
    }

    //Play audio
    function playAudio() {
        var le = document.getElementById("lang");
        var lang = le.options[le.selectedIndex].value;
        var e = document.getElementById('audio')
        setSrcQuery(e, "lang=" + lang)
        e.style.display = 'block';
        e.autoplay = 'true';
        return false;
    }

    //Switch language
    function changeLang() {
        var e = document.getElementById('audio')
        if (e.style.display == 'block') {
            playAudio();
        }
    }

    //Reload
    function reload() {
        setSrcQuery(document.getElementById('image'), "reload=" + (new Date()).getTime());
        setSrcQuery(document.getElementById('audio'), (new Date()).getTime());
        return false;
    }
</script>
<div align="center" >
    <select id="lang" onchange="changeLang()">
        < option value = "en" > English < / option >
        < option value = "zh" > Chinese < / option >
    </select>
</div>

<form action="/processCapcha" method=post align="center">
    <p>Please enter the number you see in the picture below:</p>
    <p><img id=image></p>
    < a href = "#" onclick = "reload()" > reload < / a > | < a href = "#" onclick = "playaudio()" > play audio verification code</a>

    <audio id=audio controls style="display:none" preload=none>
        You browser doesn't support audio.
        < a href = "/ captcha / download / {. Captchaid}}. Wav" > download the file < / a > to play it in the external player
    </audio>

    <input type=hidden name=captchaId value="{{.CaptchaId}}" align=center><br>
    <input name=captchaSolution align=center>
    <input type=submit value=Submit>
</form>

main.go

  • Display verification code
  • Processing verification code and result display
  • Overload verification code
  • Play verification code audio
package main

import (
    "github.com/dchest/captcha"
    "io"
    "io/ioutil"
    "log"
    "net/http"
    "text/template"
)

const filePath = "./my_captcha.html"
//Read HTML file
func readHtml() string {
    var bytes []byte
    var err error
    if bytes, err = ioutil.ReadFile(filePath); err != nil {
        log.Fatalf("ioutil.ReadFile error filePath =  %s , err :"+filePath, err)
        return ""
    }

    return string(bytes)
}

//Read the HTML file and turn it into a template.template pointer
var formTemplate = template.Must(template.New("myCaptcha").Parse(readHtml()))

//Display verification code
func showCaptcha(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        http.NotFound(w, r)
        return
    }
    d := struct {
        CaptchaId string
    }{
        captcha.New(),
    }
    //Execute applies the parsed template to the specified data object and writes the output to wr
    if err := formTemplate.Execute(w, &d); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

//Process the verification code and jump to the result page
func resultPage(w http.ResponseWriter, r *http.Request) {

    w.Header().Set("Content-Type", "text/html; charset=utf-8")

    if !captcha.VerifyString(r.FormValue("captchaId"), r.FormValue("captchaSolution")) {
        Io. Writestring (W, "incorrect verification code, please re-enter \ n")
    } else {
        Io. Writestring (W, "verify? Correct, you're great!! \ n")
    }
    Io. Writestring (W, "< br > < a href = '/' > try again < / a >")
}

func main() {

    //Simply set the log parameter
    log.SetFlags(log.Lshortfile | log.LstdFlags)

    http.HandleFunc("/", showCaptcha)
    http.HandleFunc("/processCapcha", resultPage)
    
    http.Handle("/captcha/", captcha.Server(captcha.StdWidth, captcha.StdHeight))

    log.Println("starting server : 8888")

    if err := http.ListenAndServe("localhost:8888", nil); err != nil {
        log.Fatal(err)
    }
}

The width and height of the above code are as follows

StdWidth  = 240
StdHeight = 80

aboveHandleFuncThe callback function of is like this. I shared it when I introduced gin before. You can look back at the article and let’s explore the code flow of net / HTTP

// HandleFunc registers the handler function for the given pattern
    // in the DefaultServeMux.
    // The documentation for ServeMux explains how patterns are matched.
    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    }

Verification code actual effect

Let's play the verification code with go

When you click play audio verification code, you can see this effect

Let's play the verification code with go

The audio will play different voice and read the numbers on the picture according to the language we choose

Let's play the verification code with go

summary

  • Sort of verification code
  • Installation of verification code library
  • Verification code library source code introduction
  • Practice, coding
  • Verification code effect display

Welcome to like, follow and collect

My friends, your support and encouragement are the driving force for me to insist on sharing and improve quality

Let's play the verification code with go

Well, that’s all for this time,How to send mail next time using Golf

Technology is open, and our mentality should be open. Embrace change, live in the sun and strive to move forward.

I amLittle Devil boy Nezha, welcome to like and pay attention to the collection. See you next time~