使用Go語言破解滑塊驗證碼的完整流程

啊飒飒大苏打發表於2024-10-11

在本文中,我們將透過 Go 語言破解滑塊驗證碼,逐步講解如何計算滑塊移動距離、生成軌跡並提交驗證請求。

  1. 下載驗證碼圖片
    使用 Go 的 net/http 庫來獲取驗證碼圖片,並儲存到本地。

package main

import (
"fmt"
"io/ioutil"
"net/http"
"os"
)

func downloadImage(url string, filePath string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
	return err
}

err = ioutil.WriteFile(filePath, body, 0644)
if err != nil {
	return err
}

fmt.Printf("Downloaded image from %s\n", url)
return nil

}

func main() {
downloadImage("https://captcha.com/bg.png", "background.png")
downloadImage("https://captcha.com/fg.png", "foreground.png")
}
2. 計算滑塊移動距離
為了計算滑塊移動的距離,我們需要將前景圖片和背景圖片進行對比。Go 語言的 image 庫可以幫助我們處理影像操作。

package main

import (
"fmt"
"image"
"image/jpeg"
"os"

"golang.org/x/image/draw"

)

func calculateDistance(bgPath, fgPath string) (int, error) {
bgFile, err := os.Open(bgPath)
if err != nil {
return 0, err
}
defer bgFile.Close()

fgFile, err := os.Open(fgPath)
if err != nil {
	return 0, err
}
defer fgFile.Close()

bgImg, err := jpeg.Decode(bgFile)
if err != nil {
	return 0, err
}

fgImg, err := jpeg.Decode(fgFile)
if err != nil {
	return 0, err
}

bounds := bgImg.Bounds()
for x := 0; x < bounds.Max.X; x++ {
	for y := 0; y < bounds.Max.Y; y++ {
		bgPixel := bgImg.At(x, y)
		fgPixel := fgImg.At(x, y)
		if !isPixelSimilar(bgPixel, fgPixel) {
			fmt.Printf("Slide distance is %d\n", x)
			return x, nil
		}
	}
}

return 0, nil

}

func isPixelSimilar(a, b image.Color) bool {
// 簡單的顏色比較
return a == b
}

func main() {
downloadImage("https://captcha.com/bg.png", "background.png")
downloadImage("https://captcha.com/fg.png", "foreground.png")
distance, err := calculateDistance("background.png", "foreground.png")
if err != nil {
fmt.Println("Error calculating distance:", err)
return
}
fmt.Println("Calculated distance:", distance)
}
3. 生成滑動軌跡
滑動軌跡應該是隨機的,並且模模擬實使用者的行為。在此,我們生成一個軌跡資料,包含 x 座標的變化和時間延遲。

package main

import (
"fmt"
"math/rand"
"time"
)

func generateTrack(distance int) ([][3]int, int) {
rand.Seed(time.Now().UnixNano())
track := make([][3]int, 0)
current := 0
totalTime := 0

for current < distance {
	move := rand.Intn(3) + 1
	current += move
	if current > distance {
		current = distance
	}
	timeDelay := rand.Intn(20) + 10
	totalTime += timeDelay
	track = append(track, [3]int{current, 0, totalTime})
}

return track, totalTime

}

func main() {
track, timeSpent := generateTrack(100)
fmt.Printf("Generated track: %v\n", track)
fmt.Printf("Time spent: %d ms\n", timeSpent)
}
4. 傳送驗證請求
我們使用 Go 的 net/http 庫傳送帶有滑動距離和軌跡的驗證請求。

package main

import (
"bytes"
"fmt"
"net/http"
"strings"
)

func sendVerification(distance int, track [][3]int) error {
trackStr := make([]string, 0, len(track))
for _, t := range track {
trackStr = append(trackStr, fmt.Sprintf("[%d,%d,%d]", t[0], t[1], t[2]))
}
trackData := strings.Join(trackStr, ",")

data := fmt.Sprintf("distance=%d&track=%s", distance, trackData)
resp, err := http.Post("https://captcha.com/verify", "application/x-www-form-urlencoded", bytes.NewBufferString(data))
if err != nil {
	return err
}
defer resp.Body.Close()

fmt.Println("Verification request sent. Response status:", resp.Status)
return nil

}
更多內容聯絡1436423940
func main() {
distance := 100
track, _ := generateTrack(distance)
sendVerification(distance, track)
}
5. 主程式整合
最後,我們將所有步驟整合起來,形成一個完整的流程。

package main

func main() {
// 1. 下載驗證碼圖片
downloadImage("https://captcha.com/bg.png", "background.png")
downloadImage("https://captcha.com/fg.png", "foreground.png")

// 2. 計算滑動距離
distance, err := calculateDistance("background.png", "foreground.png")
if err != nil {
	fmt.Println("Error calculating distance:", err)
	return
}

// 3. 生成滑動軌跡
track, _ := generateTrack(distance)

// 4. 傳送驗證請求
err = sendVerification(distance, track)
if err != nil {
	fmt.Println("Error sending verification:", err)
}

}

相關文章