1 猜数字游戏
1.1 生成随机数
package main
import (
"fmt"
"math/rand"
)
func main() {
maxNum := 100
secretNumber := rand.Intn(maxNum) //随机数函数rand.Intn(number int)//生成一个不超过number的非负整数
fmt.Println("The secret number is ", secretNumber)
}
1.2 初始化随机数种子
package main
import (
"fmt"
"math/rand"
"time"//**新加行
)
func main() {
maxNum := 1
rand.Seed(time.Now().UnixNano()) //**用时间戳来初始化随机化种子
secretNumber := rand.Intn(maxNum) //随机数函数rand.Intn(number int)//生成一个不超过number的非负整数
fmt.Println("The secret number is ", secretNumber)
}
UnixNano()定义:func (t Time) UnixNano() int64
1.3 玩家输入
package main
import (
"bufio"//**
"fmt"
"math/rand"
//**
"os"
"strconv"
"strings"
//**
"time"
)
func main() {
maxNum := 1
rand.Seed(time.Now().UnixNano()) //用时间戳来初始化随机化种子
secretNumber := rand.Intn(maxNum) //随机数函数rand.Intn(number int)//生成一个不超过number的非负整数
fmt.Println("The secret number is ", secretNumber)
//**
fmt.Println("Please input your guess")
reader := bufio.NewReader(os.Stdin) //从终端读入
input, err := reader.ReadString('\n') //读取一行
if err != nil {
fmt.Println("An error occured while reding input.Please try again", err)
return
}
input := strings.TrimSuffix(input, "\n") //减去后缀
guess, err := strconv.Atoi(input) //strconv包中的Atoi()函数将纯数字字符串转换为int类型返回
if err != nil {
fmt.Println("Invalid input.Please evter an integer value")
return
}
fmt.Println("You guess is",guess)
//**
}
reader := bufio.NewReader(os.Stdin)功能:从终端读取数据生成*Reader
os.Stdin:var Stdin *File = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
NewFile()创建/dev/stdin新文件并将终端输入数据写入,返回*File类型,所以Stdin是os库下的标准输入句柄
strings.TrimSuffix(str string,suffix)将str字符串的后缀suffix删除
strconv.Atoi(str string)将str(纯数字字符串)转换为int类型并返回
1.4 实现逻辑判断
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
func main() {
maxNum := 1
rand.Seed(time.Now().UnixNano()) //用时间戳来初始化随机化种子
secretNumber := rand.Intn(maxNum) //随机数函数rand.Intn(number int)//生成一个不超过number的非负整数
fmt.Println("The secret number is ", secretNumber)
fmt.Println("Please input your guess")
reader := bufio.NewReader(os.Stdin) //从终端读入
input, err := reader.ReadString('\n') //读取一行
if err != nil {
fmt.Println("An error occured while reding input.Please try again", err)
return
}
input := strings.TrimSuffix(input, "\n") //减去后缀
guess, err := strconv.Atoi(input) //strconv包中的Atoi()函数将纯数字字符串转换为int类型返回
if err != nil {
fmt.Println("Invalid input.Please evter an integer value")
return
}
fmt.Println("You guess is", guess)
//**
if guess > secretNumber {
fmt.Println("Your guess is bigger than the secret number.Please try again")
} else if guess < secretnumber {
fmt.Println("Your guess is smaller than the secret number.Please try again")
} else {
fmt.Println("Correct,you legend!")
}
//**
}
1.5 实现游戏循环
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
func main() {
maxNum := 1
rand.Seed(time.Now().UnixNano()) //用时间戳来初始化随机化种子
secretNumber := rand.Intn(maxNum) //随机数函数rand.Intn(number int)//生成一个不超过number的非负整数
//fmt.Println("The secret number is ", secretNumber)
fmt.Println("Please input your guess")
reader := bufio.NewReader(os.Stdin) //从终端读入
for {//**
input, err := reader.ReadString('\n') //读取一行
if err != nil {
fmt.Println("An error occured while reding input.Please try again", err)
//return
continue//**
}
input := strings.TrimSuffix(input, "\r\n") //减去后缀
guess, err := strconv.Atoi(input) //strconv包中的Atoi()函数将纯数字字符串转换为int类型返回
if err != nil {
fmt.Println("Invalid input.Please evter an integer value")
//return
continue//**
}
fmt.Println("You guess is", guess)
if guess > secretNumber {
fmt.Println("Your guess is bigger than the secret number.Please try again")
} else if guess < secretnumber {
fmt.Println("Your guess is smaller than the secret number.Please try again")
} else {
fmt.Println("Correct,you legend!")
break//**
}
}//**
}
1.6 最终代码实现
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano()) //用时间戳来初始化随机化种子
secretNumber := rand.Intn(maxNum) //随机数函数rand.Intn(number int)//生成一个不超过number的非负整数
fmt.Println("Please input your guess")
reader := bufio.NewReader(os.Stdin) //从终端读入
for {
input, err := reader.ReadString('\n') //读取一行
if err != nil {
fmt.Println("An error occured while reding input.Please try again", err)
continue
}
input = strings.TrimSuffix(input, "\r\n") //删除字符串中的\t\r\n
guess, err := strconv.Atoi(input) //strconv包中的Atoi()函数将纯数字字符串转换为int类型返回
if err != nil {
fmt.Println("Invalid input.Please enter an integer value.err:", err)
continue
}
fmt.Println("You guess is", guess)
if guess > secretNumber {
fmt.Println("Your guess is bigger than the secret number.Please try again")
} else if guess < secretNumber {
fmt.Println("Your guess is smaller than the secret number.Please try again")
} else {
fmt.Println("Correct,you legend!")
break
}
}
}
2 在线词典
因为这个项目涉及许多我不了解的知识,所以我只能跟着视频敲代码,下面是可运行代码:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
//"strings"
)
type DictRequest struct {
TransType string `json:"trans_type"`
Source string `json:"source"`
UserID string `json:"user_id"`
}
type DiciResponse struct {
Rc int `json:"rc"`
Wiki struct {
} `json:"wiki"`
Dictionary struct {
Prons struct {
EnUs string `json:"en-us"`
En string `json:"en"`
} `json:"prons"`
Explanations []string `json:"explanations"`
Synonym []string `json:"synonym"`
Antonym []string `json:"antonym"`
WqxExample [][]string `json:"wqx_example"`
Entry string `json:"entry"`
Type string `json:"type"`
Related []interface{} `json:"related"`
Source string `json:"source"`
} `json:"dictionary"`
}
func query(word string) {
client := &http.Client{}
//var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
request := DictRequest{TransType: "en2zh", Source: word}
buf, err := json.Marshal(request) //序列化,返回[]byte
if err != nil {
log.Fatal(err)
}
var data = bytes.NewReader(buf)
//创建请求头
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
if err != nil {
log.Fatal(err)
}
//设置请求头
req.Header.Set("authority", "api.interpreter.caiyunai.com")
req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="8"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.1.5162 SLBChan/11")
req.Header.Set("app-name", "xy")
req.Header.Set("content-type", "application/json;charset=UTF-8")
req.Header.Set("accept", "application/json, text/plain, */*")
req.Header.Set("device-id", "dd0afa32b571973a3e17558bb28dc3a3")
req.Header.Set("os-type", "web")
req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
req.Header.Set("origin", "https://fanyi.caiyunapp.com")
req.Header.Set("sec-fetch-site", "cross-site")
req.Header.Set("sec-fetch-mode", "cors")
req.Header.Set("sec-fetch-dest", "empty")
req.Header.Set("referer", "https://fanyi.caiyunapp.com/")
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
resp, err := client.Do(req) //发起请求
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close() //手动关闭流
bodyText, err := io.ReadAll(resp.Body) //读取相应,返回的是[]byte数组
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != 200 {
log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
}
//fmt.Printf("%s\n", bodyText) //打印json字符串
var dictResponse DiciResponse
err = json.Unmarshal(bodyText, &dictResponse) //反序列化
if err != nil {
log.Fatal(err)
}
//fmt.Printf("%#v\n", dictResponse)
fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
for _, item := range dictResponse.Dictionary.Explanations {
fmt.Println(item)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Fprint(os.Stderr, `usage: simpleDict WORD example: simpleDict hello`)
os.Exit(1)
}
word := os.Args[1]
query(word)
}
3 SOCKS5代理介绍
代码示例:
package main
import (
"bufio"
"context"
"encoding/binary"
"errors"
"fmt"
"io"
"log"
"net"
)
const (
socks5Ver = 0x05
cmdBind = 0x01
atypIPV4 = 0x01
atypeHOST = 0x03
atypeIPV6 = 0x04
)
func main() {
sever, err := net.Listen("tcp", "127.0.0.1:1080") //征信一个端口
if err != nil {
panic(err)
}
for {
client, err := sever.Accept() //接受一个请求,返回连接
if err != nil {
log.Printf("Accept failed %v", err)
continue
}
go process(client) //启动一个协程
}
}
func process(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn) //只读的带缓冲的流
err := auth(reader, conn)
if err != nil {
log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)
return
}
//log.Println("auth success")
err = connect(reader, conn)
if err != nil {
log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)
return
}
}
func auth(reader *bufio.Reader, conn net.Conn) (err error) {
ver, err := reader.ReadByte()
if err != nil {
return fmt.Errorf("read ver failed:%w", ver)
}
if ver != socks5Ver {
return fmt.Errorf("not srpported ver:%v", ver)
}
methodSize, err := reader.ReadByte()
if err != nil {
return fmt.Errorf("read methodSize failed:%w", err)
}
method := make([]byte, methodSize)
_, err = io.ReadFull(reader, method)
if err != nil {
return fmt.Errorf("read method failed:%w", err)
}
log.Println("ver", ver, "method", method)
_, err = conn.Write([]byte{socks5Ver, 0x00})
if err != nil {
return fmt.Errorf("write failed:%w", err)
}
return nil
}
func connect(reader *bufio.Reader, conn net.Conn) (err error) {
buf := make([]byte, 4)
_, err = io.ReadFull(reader, buf)
if err != nil {
return fmt.Errorf("read header failed:%w", err)
}
ver, cmd, atyp := buf[0], buf[1], buf[2]
if ver != socks5Ver {
return fmt.Errorf("not supported ver:%v", ver)
}
if cmd != cmdBind {
return fmt.Errorf("not supported cmd:%v", ver)
}
addr := ""
switch atyp {
case atypIPV4:
_, err = io.ReadFull(reader, buf)
if err != nil {
return fmt.Errorf("read atyp failed:%w", err)
}
addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3])
case atypeHOST:
hostSize, err := reader.ReadByte()
if err != nil {
return fmt.Errorf("read hostSize failed:%w", err)
}
host := make([]byte, hostSize)
_, err = io.ReadFull(reader, host)
if err != nil {
return fmt.Errorf("read host failed:%w", err)
}
addr = string(host)
case atypeIPV6:
return errors.New("IPV6: no supported yet")
default:
return errors.New("invalid atyp")
}
_, err = io.ReadFull(reader, buf[:2])
if err != nil {
return fmt.Errorf("read port failed:%w")
}
port := binary.BigEndian.Uint16(buf[:2])
dest, err := net.Dial("tcp", fmt.Sprintf("%v:L%v", addr, port))
if err != nil {
return fmt.Errorf("dial dst failed:%w", err)
}
defer dest.Close()
log.Println("dial", addr, port)
_, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})
if err != nil {
return fmt.Errorf("write failed: %w", err)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
_, _ = io.Copy(dest, reader)
cancel()
}()
go func() {
_, _ = io.Copy(conn, dest)
cancel()
}()
<-ctx.Done()
return nil
}