Go语言实战 | 青训营笔记

132 阅读3分钟

猜谜游戏

package main

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

func main() {
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(100)
	maxGuesses := 10
	numGuesses := 0

	fmt.Println("欢迎参加猜谜游戏!")
	fmt.Println("我想了一个0到99之间的秘密数字。你有10次机会猜出它。")

	for {
		fmt.Printf("剩余猜测次数:%d\n", maxGuesses-numGuesses)
		fmt.Print("请输入你的猜测:")
		var guess int
		_, err := fmt.Scanf("%d", &guess)

		if err != nil {
			fmt.Println("输入无效,请输入一个整数。")
			continue
		}

		if guess < secretNumber {
			fmt.Println("太小了!")
		} else if guess > secretNumber {
			fmt.Println("太大了!")
		} else {
			fmt.Println("恭喜你,猜对了!")
			break
		}

		numGuesses++

		if numGuesses == maxGuesses {
			fmt.Println("很遗憾,你没有猜对。正确答案是:", secretNumber)
			break
		}
	}
}

该程序会随机生成一个0到99之间的秘密数字,然后你有10次机会猜出这个数字。每次猜测后,程序会告诉你猜测的数字是太大了还是太小了,直到你猜对或者用完所有的猜测次数。

命令行词典

package main

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

// 在线词典查询
func dictionaryLookup(word string) {
	apiURL := "https://api.dictionary.com/api/v3/references/learners/json/" + word

	resp, err := http.Get(apiURL)
	if err != nil {
		fmt.Println("请求失败:", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取响应失败:", err)
		return
	}

	fmt.Println(string(body))
}

// 网页翻译抓包
func webTranslationCapture(urlStr string) {
	resp, err := http.Get(urlStr)
	if err != nil {
		fmt.Println("请求失败:", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取响应失败:", err)
		return
	}

	fmt.Println(string(body))
}

func main() {
	// 在线词典查询示例
	dictionaryLookup("apple")

	// 网页翻译抓包示例
	urlStr := "https://www.example.com"
	webTranslationCapture(urlStr)
}

定义了两个函数:dictionaryLookup用于在线词典查询,webTranslationCapture用于网页翻译抓包

SOCKS5代理

package main

import (
	"fmt"
	"io"
	"log"
	"net"
)

func main() {
	// 监听代理端口
	proxyListener, err := net.Listen("tcp", "127.0.0.1:1080")
	if err != nil {
		log.Fatal("Failed to start proxy server:", err)
	}
	defer proxyListener.Close()
	fmt.Println("Proxy server started on 127.0.0.1:1080")

	for {
		// 接受客户端连接
		clientConn, err := proxyListener.Accept()
		if err != nil {
			log.Println("Failed to accept client connection:", err)
			continue
		}

		// 开始处理客户端请求
		go handleClientRequest(clientConn)
	}
}

func handleClientRequest(clientConn net.Conn) {
	defer clientConn.Close()

	// 读取客户端版本和认证方法
	buf := make([]byte, 258)
	_, err := io.ReadFull(clientConn, buf[:2])
	if err != nil {
		log.Println("Failed to read client version and auth methods:", err)
		return
	}

	// 只支持 SOCKS5
	if buf[0] != 0x05 {
		log.Println("Unsupported SOCKS version:", buf[0])
		return
	}

	// 只支持无需认证
	if buf[1] != 0x01 {
		log.Println("Unsupported auth method:", buf[1])
		return
	}

	// 发送服务器版本和认证方法
	_, err = clientConn.Write([]byte{0x05, 0x00})
	if err != nil {
		log.Println("Failed to write server version and auth method:", err)
		return
	}

	// 读取客户端请求
	_, err = io.ReadFull(clientConn, buf[:4])
	if err != nil {
		log.Println("Failed to read client request:", err)
		return
	}

	// 只支持 CONNECT 请求
	if buf[1] != 0x01 {
		log.Println("Unsupported request type:", buf[1])
		return
	}

	// 解析目标地址
	var targetIP net.IP
	var targetPort uint16
	switch buf[3] {
	case 0x01:
		// IPv4 地址
		_, err = io.ReadFull(clientConn, buf[:4])
		if err != nil {
			log.Println("Failed to read IPv4 address:", err)
			return
		}
		targetIP = net.IP(buf[:4])
	case 0x03:
		// 域名
		_, err = io.ReadFull(clientConn, buf[:1])
		if err != nil {
			log.Println("Failed to read domain length:", err)
			return
		}
		domainLength := int(buf[0])
		_, err = io.ReadFull(clientConn, buf[:domainLength])
		if err != nil {
			log.Println("Failed to read domain:", err)
			return
		}
		targetIP = net.ParseIP(string(buf[:domainLength]))
	case 0x04:
		// IPv6 地址
		_, err = io.ReadFull(clientConn, buf[:16])
		if err != nil {
			log.Println("Failed to read IPv6 address:", err)
			return
		}
		targetIP = net.IP(buf[:16])
	default:
		log.Println("Unsupported address type:", buf[3])
		return
	}

	// 读取目标端口
	_, err = io.ReadFull(clientConn, buf[:2])
	if err != nil {
		log.Println("Failed to read target port:", err)
		return
	}
	targetPort = (uint16(buf[0]) << 8) | uint16(buf[1])

	// 建立与目标服务器的连接
	targetConn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", targetIP.String(), targetPort))
	if err != nil {
		log.Println("Failed to connect to target:", err)
		return
	}
	defer targetConn.Close()

	// 发送连接成功的响应给客户端
	_, err = clientConn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
	if err != nil {
		log.Println("Failed to write connection established response:", err)
		return
	}

	// 在两个连接之间进行数据传输
	go io.Copy(targetConn, clientConn)
	io.Copy(clientConn, targetConn)
}

创建一个在本地监听 1080 端口的 SOCKS5 代理服务器。它接受来自客户端的请求并建立与目标服务器的连接,然后在两个连接之间进行数据传输。