├── .gitpod.yml ├── README.md ├── example ├── 01-hello │ └── main.go ├── 02-var │ └── main.go ├── 03-for │ └── main.go ├── 04-if │ └── main.go ├── 05-switch │ └── main.go ├── 06-array │ └── main.go ├── 07-slice │ └── main.go ├── 08-map │ └── main.go ├── 09-range │ └── main.go ├── 10-func │ └── main.go ├── 11-point │ └── main.go ├── 12-struct │ └── main.go ├── 13-struct-method │ └── main.go ├── 14-error │ └── main.go ├── 15-string │ └── main.go ├── 16-fmt │ └── main.go ├── 17-json │ └── main.go ├── 18-time │ └── main.go ├── 19-strconv │ └── main.go └── 20-env │ └── main.go ├── go.mod ├── go.sum ├── guessing-game ├── v1 │ └── main.go ├── v2 │ └── main.go ├── v3 │ └── main.go ├── v4 │ └── main.go └── v5 │ └── main.go ├── proxy ├── v1 │ └── main.go ├── v2 │ └── main.go ├── v3 │ └── main.go └── v4 │ └── main.go └── simpledict ├── v1 └── main.go ├── v2 └── main.go ├── v3 └── main.go └── v4 └── main.go /.gitpod.yml: -------------------------------------------------------------------------------- 1 | vscode: 2 | extensions: 3 | - golang.go 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-by-example 2 | 3 | Go 语言上手配套实例代码 4 | 5 | ### [点此查看配套学员手册](https://bytedance.feishu.cn/docx/doxcnZEMaiB9EGzZ0Z97WULAWOL) 6 | 7 | ### [点此在线运行代码](https://gitpod.io/#github.com/wangkechun/go-by-example) 8 | 9 | ### 目录结构 10 | 11 | - [example](./example) 12 | - [guessing-game 猜谜游戏](./guessing-game/) 13 | - [simpledict 命令行词典](./simpledict/) 14 | - [proxy SOCKS5 代理](./proxy/) 15 | -------------------------------------------------------------------------------- /example/01-hello/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("hello world") 9 | } 10 | -------------------------------------------------------------------------------- /example/02-var/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | 10 | var a = "initial" 11 | 12 | var b, c int = 1, 2 13 | 14 | var d = true 15 | 16 | var e float64 17 | 18 | f := float32(e) 19 | 20 | g := a + "foo" 21 | fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0 22 | fmt.Println(g) // initialapple 23 | 24 | const s string = "constant" 25 | const h = 500000000 26 | const i = 3e20 / h 27 | fmt.Println(s, h, i, math.Sin(h), math.Sin(i)) 28 | } 29 | -------------------------------------------------------------------------------- /example/03-for/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | i := 1 8 | for { 9 | fmt.Println("loop") 10 | break 11 | } 12 | for j := 7; j < 9; j++ { 13 | fmt.Println(j) 14 | } 15 | 16 | for n := 0; n < 5; n++ { 17 | if n%2 == 0 { 18 | continue 19 | } 20 | fmt.Println(n) 21 | } 22 | for i <= 3 { 23 | fmt.Println(i) 24 | i = i + 1 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/04-if/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | if 7%2 == 0 { 8 | fmt.Println("7 is even") 9 | } else { 10 | fmt.Println("7 is odd") 11 | } 12 | 13 | if 8%4 == 0 { 14 | fmt.Println("8 is divisible by 4") 15 | } 16 | 17 | if num := 9; num < 0 { 18 | fmt.Println(num, "is negative") 19 | } else if num < 10 { 20 | fmt.Println(num, "has 1 digit") 21 | } else { 22 | fmt.Println(num, "has multiple digits") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/05-switch/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | 10 | a := 2 11 | switch a { 12 | case 1: 13 | fmt.Println("one") 14 | case 2: 15 | fmt.Println("two") 16 | case 3: 17 | fmt.Println("three") 18 | case 4, 5: 19 | fmt.Println("four or five") 20 | default: 21 | fmt.Println("other") 22 | } 23 | 24 | t := time.Now() 25 | switch { 26 | case t.Hour() < 12: 27 | fmt.Println("It's before noon") 28 | default: 29 | fmt.Println("It's after noon") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/06-array/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var a [5]int 8 | a[4] = 100 9 | fmt.Println("get:", a[2]) 10 | fmt.Println("len:", len(a)) 11 | 12 | b := [5]int{1, 2, 3, 4, 5} 13 | fmt.Println(b) 14 | 15 | var twoD [2][3]int 16 | for i := 0; i < 2; i++ { 17 | for j := 0; j < 3; j++ { 18 | twoD[i][j] = i + j 19 | } 20 | } 21 | fmt.Println("2d: ", twoD) 22 | } 23 | -------------------------------------------------------------------------------- /example/07-slice/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | s := make([]string, 3) 8 | s[0] = "a" 9 | s[1] = "b" 10 | s[2] = "c" 11 | fmt.Println("get:", s[2]) // c 12 | fmt.Println("len:", len(s)) // 3 13 | 14 | s = append(s, "d") 15 | s = append(s, "e", "f") 16 | fmt.Println(s) // [a b c d e f] 17 | 18 | c := make([]string, len(s)) 19 | copy(c, s) 20 | fmt.Println(c) // [a b c d e f] 21 | 22 | fmt.Println(s[2:5]) // [c d e] 23 | fmt.Println(s[:5]) // [a b c d e] 24 | fmt.Println(s[2:]) // [c d e f] 25 | 26 | good := []string{"g", "o", "o", "d"} 27 | fmt.Println(good) // [g o o d] 28 | } 29 | -------------------------------------------------------------------------------- /example/08-map/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | m := make(map[string]int) 7 | m["one"] = 1 8 | m["two"] = 2 9 | fmt.Println(m) // map[one:1 two:2] 10 | fmt.Println(len(m)) // 2 11 | fmt.Println(m["one"]) // 1 12 | fmt.Println(m["unknow"]) // 0 13 | 14 | r, ok := m["unknow"] 15 | fmt.Println(r, ok) // 0 false 16 | 17 | delete(m, "one") 18 | 19 | m2 := map[string]int{"one": 1, "two": 2} 20 | var m3 = map[string]int{"one": 1, "two": 2} 21 | fmt.Println(m2, m3) 22 | } 23 | -------------------------------------------------------------------------------- /example/09-range/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | nums := []int{2, 3, 4} 7 | sum := 0 8 | for i, num := range nums { 9 | sum += num 10 | if num == 2 { 11 | fmt.Println("index:", i, "num:", num) // index: 0 num: 2 12 | } 13 | } 14 | fmt.Println(sum) // 9 15 | 16 | m := map[string]string{"a": "A", "b": "B"} 17 | for k, v := range m { 18 | fmt.Println(k, v) // b 8; a A 19 | } 20 | for k := range m { 21 | fmt.Println("key", k) // key a; key b 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/10-func/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func add(a int, b int) int { 6 | return a + b 7 | } 8 | 9 | func add2(a, b int) int { 10 | return a + b 11 | } 12 | 13 | func exists(m map[string]string, k string) (v string, ok bool) { 14 | v, ok = m[k] 15 | return v, ok 16 | } 17 | 18 | func main() { 19 | res := add(1, 2) 20 | fmt.Println(res) // 3 21 | 22 | v, ok := exists(map[string]string{"a": "A"}, "a") 23 | fmt.Println(v, ok) // A True 24 | } 25 | -------------------------------------------------------------------------------- /example/11-point/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func add2(n int) { 6 | n += 2 7 | } 8 | 9 | func add2ptr(n *int) { 10 | *n += 2 11 | } 12 | 13 | func main() { 14 | n := 5 15 | add2(n) 16 | fmt.Println(n) // 5 17 | add2ptr(&n) 18 | fmt.Println(n) // 7 19 | } 20 | -------------------------------------------------------------------------------- /example/12-struct/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type user struct { 6 | name string 7 | password string 8 | } 9 | 10 | func main() { 11 | a := user{name: "wang", password: "1024"} 12 | b := user{"wang", "1024"} 13 | c := user{name: "wang"} 14 | c.password = "1024" 15 | var d user 16 | d.name = "wang" 17 | d.password = "1024" 18 | 19 | fmt.Println(a, b, c, d) // {wang 1024} {wang 1024} {wang 1024} {wang 1024} 20 | fmt.Println(checkPassword(a, "haha")) // false 21 | fmt.Println(checkPassword2(&a, "haha")) // false 22 | } 23 | 24 | func checkPassword(u user, password string) bool { 25 | return u.password == password 26 | } 27 | 28 | func checkPassword2(u *user, password string) bool { 29 | return u.password == password 30 | } 31 | -------------------------------------------------------------------------------- /example/13-struct-method/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type user struct { 6 | name string 7 | password string 8 | } 9 | 10 | func (u user) checkPassword(password string) bool { 11 | return u.password == password 12 | } 13 | 14 | func (u *user) resetPassword(password string) { 15 | u.password = password 16 | } 17 | 18 | func main() { 19 | a := user{name: "wang", password: "1024"} 20 | a.resetPassword("2048") 21 | fmt.Println(a.checkPassword("2048")) // true 22 | } 23 | -------------------------------------------------------------------------------- /example/14-error/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | type user struct { 9 | name string 10 | password string 11 | } 12 | 13 | func findUser(users []user, name string) (v *user, err error) { 14 | for _, u := range users { 15 | if u.name == name { 16 | return &u, nil 17 | } 18 | } 19 | return nil, errors.New("not found") 20 | } 21 | 22 | func main() { 23 | u, err := findUser([]user{{"wang", "1024"}}, "wang") 24 | if err != nil { 25 | fmt.Println(err) 26 | return 27 | } 28 | fmt.Println(u.name) // wang 29 | 30 | if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil { 31 | fmt.Println(err) // not found 32 | return 33 | } else { 34 | fmt.Println(u.name) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /example/15-string/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | a := "hello" 10 | fmt.Println(strings.Contains(a, "ll")) // true 11 | fmt.Println(strings.Count(a, "l")) // 2 12 | fmt.Println(strings.HasPrefix(a, "he")) // true 13 | fmt.Println(strings.HasSuffix(a, "llo")) // true 14 | fmt.Println(strings.Index(a, "ll")) // 2 15 | fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo 16 | fmt.Println(strings.Repeat(a, 2)) // hellohello 17 | fmt.Println(strings.Replace(a, "e", "E", -1)) // hEllo 18 | fmt.Println(strings.Split("a-b-c", "-")) // [a b c] 19 | fmt.Println(strings.ToLower(a)) // hello 20 | fmt.Println(strings.ToUpper(a)) // HELLO 21 | fmt.Println(len(a)) // 5 22 | b := "你好" 23 | fmt.Println(len(b)) // 6 24 | } 25 | -------------------------------------------------------------------------------- /example/16-fmt/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type point struct { 6 | x, y int 7 | } 8 | 9 | func main() { 10 | s := "hello" 11 | n := 123 12 | p := point{1, 2} 13 | fmt.Println(s, n) // hello 123 14 | fmt.Println(p) // {1 2} 15 | 16 | fmt.Printf("s=%v\n", s) // s=hello 17 | fmt.Printf("n=%v\n", n) // n=123 18 | fmt.Printf("p=%v\n", p) // p={1 2} 19 | fmt.Printf("p=%+v\n", p) // p={x:1 y:2} 20 | fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2} 21 | 22 | f := 3.141592653 23 | fmt.Println(f) // 3.141592653 24 | fmt.Printf("%.2f\n", f) // 3.14 25 | } 26 | -------------------------------------------------------------------------------- /example/17-json/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type userInfo struct { 9 | Name string 10 | Age int `json:"age"` 11 | Hobby []string 12 | } 13 | 14 | func main() { 15 | a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}} 16 | buf, err := json.Marshal(a) 17 | if err != nil { 18 | panic(err) 19 | } 20 | fmt.Println(buf) // [123 34 78 97...] 21 | fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]} 22 | 23 | buf, err = json.MarshalIndent(a, "", "\t") 24 | if err != nil { 25 | panic(err) 26 | } 27 | fmt.Println(string(buf)) 28 | 29 | var b userInfo 30 | err = json.Unmarshal(buf, &b) 31 | if err != nil { 32 | panic(err) 33 | } 34 | fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}} 35 | } 36 | -------------------------------------------------------------------------------- /example/18-time/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | now := time.Now() 10 | fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933 11 | t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC) 12 | t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC) 13 | fmt.Println(t) // 2022-03-27 01:25:36 +0000 UTC 14 | fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25 15 | fmt.Println(t.Format("2006-01-02 15:04:05")) // 2022-03-27 01:25:36 16 | diff := t2.Sub(t) 17 | fmt.Println(diff) // 1h5m0s 18 | fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900 19 | t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36") 20 | if err != nil { 21 | panic(err) 22 | } 23 | fmt.Println(t3 == t) // true 24 | fmt.Println(now.Unix()) // 1648738080 25 | } 26 | -------------------------------------------------------------------------------- /example/19-strconv/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | f, _ := strconv.ParseFloat("1.234", 64) 10 | fmt.Println(f) // 1.234 11 | 12 | n, _ := strconv.ParseInt("111", 10, 64) 13 | fmt.Println(n) // 111 14 | 15 | n, _ = strconv.ParseInt("0x1000", 0, 64) 16 | fmt.Println(n) // 4096 17 | 18 | n2, _ := strconv.Atoi("123") 19 | fmt.Println(n2) // 123 20 | 21 | n2, err := strconv.Atoi("AAA") 22 | fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax 23 | } 24 | -------------------------------------------------------------------------------- /example/20-env/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | ) 8 | 9 | func main() { 10 | // go run example/20-env/main.go a b c d 11 | fmt.Println(os.Args) // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d] 12 | fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin... 13 | fmt.Println(os.Setenv("AA", "BB")) 14 | 15 | buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput() 16 | if err != nil { 17 | panic(err) 18 | } 19 | fmt.Println(string(buf)) // 127.0.0.1 localhost 20 | } 21 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wangkechun/go-by-example 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangkechun/go-by-example/4c131ea0d6d8f62b2756c6a8fa70362074e7a0df/go.sum -------------------------------------------------------------------------------- /guessing-game/v1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | ) 7 | 8 | func main() { 9 | maxNum := 100 10 | secretNumber := rand.Intn(maxNum) 11 | fmt.Println("The secret number is ", secretNumber) 12 | } 13 | -------------------------------------------------------------------------------- /guessing-game/v2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | maxNum := 100 11 | rand.Seed(time.Now().UnixNano()) 12 | secretNumber := rand.Intn(maxNum) 13 | fmt.Println("The secret number is ", secretNumber) 14 | } 15 | -------------------------------------------------------------------------------- /guessing-game/v3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "math/rand" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func main() { 14 | maxNum := 100 15 | rand.Seed(time.Now().UnixNano()) 16 | secretNumber := rand.Intn(maxNum) 17 | fmt.Println("The secret number is ", secretNumber) 18 | 19 | fmt.Println("Please input your guess") 20 | reader := bufio.NewReader(os.Stdin) 21 | input, err := reader.ReadString('\n') 22 | if err != nil { 23 | fmt.Println("An error occured while reading input. Please try again", err) 24 | return 25 | } 26 | input = strings.Trim(input, "\r\n") 27 | 28 | guess, err := strconv.Atoi(input) 29 | if err != nil { 30 | fmt.Println("Invalid input. Please enter an integer value") 31 | return 32 | } 33 | fmt.Println("You guess is", guess) 34 | } 35 | -------------------------------------------------------------------------------- /guessing-game/v4/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "math/rand" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func main() { 14 | maxNum := 100 15 | rand.Seed(time.Now().UnixNano()) 16 | secretNumber := rand.Intn(maxNum) 17 | fmt.Println("The secret number is ", secretNumber) 18 | 19 | fmt.Println("Please input your guess") 20 | reader := bufio.NewReader(os.Stdin) 21 | input, err := reader.ReadString('\n') 22 | if err != nil { 23 | fmt.Println("An error occured while reading input. Please try again", err) 24 | return 25 | } 26 | input = strings.Trim(input, "\r\n") 27 | 28 | guess, err := strconv.Atoi(input) 29 | if err != nil { 30 | fmt.Println("Invalid input. Please enter an integer value") 31 | return 32 | } 33 | fmt.Println("You guess is", guess) 34 | if guess > secretNumber { 35 | fmt.Println("Your guess is bigger than the secret number. Please try again") 36 | } else if guess < secretNumber { 37 | fmt.Println("Your guess is smaller than the secret number. Please try again") 38 | } else { 39 | fmt.Println("Correct, you Legend!") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /guessing-game/v5/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "math/rand" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func main() { 14 | maxNum := 100 15 | rand.Seed(time.Now().UnixNano()) 16 | secretNumber := rand.Intn(maxNum) 17 | // fmt.Println("The secret number is ", secretNumber) 18 | 19 | fmt.Println("Please input your guess") 20 | reader := bufio.NewReader(os.Stdin) 21 | for { 22 | input, err := reader.ReadString('\n') 23 | if err != nil { 24 | fmt.Println("An error occured while reading input. Please try again", err) 25 | continue 26 | } 27 | input = strings.Trim(input, "\r\n") 28 | 29 | guess, err := strconv.Atoi(input) 30 | if err != nil { 31 | fmt.Println("Invalid input. Please enter an integer value") 32 | continue 33 | } 34 | fmt.Println("You guess is", guess) 35 | if guess > secretNumber { 36 | fmt.Println("Your guess is bigger than the secret number. Please try again") 37 | } else if guess < secretNumber { 38 | fmt.Println("Your guess is smaller than the secret number. Please try again") 39 | } else { 40 | fmt.Println("Correct, you Legend!") 41 | break 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /proxy/v1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "log" 6 | "net" 7 | ) 8 | 9 | func main() { 10 | server, err := net.Listen("tcp", "127.0.0.1:1080") 11 | if err != nil { 12 | panic(err) 13 | } 14 | for { 15 | client, err := server.Accept() 16 | if err != nil { 17 | log.Printf("Accept failed %v", err) 18 | continue 19 | } 20 | go process(client) 21 | } 22 | } 23 | 24 | func process(conn net.Conn) { 25 | defer conn.Close() 26 | reader := bufio.NewReader(conn) 27 | for { 28 | b, err := reader.ReadByte() 29 | if err != nil { 30 | break 31 | } 32 | _, err = conn.Write([]byte{b}) 33 | if err != nil { 34 | break 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /proxy/v2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net" 9 | ) 10 | 11 | const socks5Ver = 0x05 12 | const cmdBind = 0x01 13 | const atypeIPV4 = 0x01 14 | const atypeHOST = 0x03 15 | const atypeIPV6 = 0x04 16 | 17 | func main() { 18 | server, err := net.Listen("tcp", "127.0.0.1:1080") 19 | if err != nil { 20 | panic(err) 21 | } 22 | for { 23 | client, err := server.Accept() 24 | if err != nil { 25 | log.Printf("Accept failed %v", err) 26 | continue 27 | } 28 | go process(client) 29 | } 30 | } 31 | 32 | func process(conn net.Conn) { 33 | defer conn.Close() 34 | reader := bufio.NewReader(conn) 35 | err := auth(reader, conn) 36 | if err != nil { 37 | log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err) 38 | return 39 | } 40 | log.Println("auth success") 41 | } 42 | 43 | func auth(reader *bufio.Reader, conn net.Conn) (err error) { 44 | // +----+----------+----------+ 45 | // |VER | NMETHODS | METHODS | 46 | // +----+----------+----------+ 47 | // | 1 | 1 | 1 to 255 | 48 | // +----+----------+----------+ 49 | // VER: 协议版本,socks5为0x05 50 | // NMETHODS: 支持认证的方法数量 51 | // METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。RFC预定义了一些值的含义,内容如下: 52 | // X’00’ NO AUTHENTICATION REQUIRED 53 | // X’02’ USERNAME/PASSWORD 54 | 55 | ver, err := reader.ReadByte() 56 | if err != nil { 57 | return fmt.Errorf("read ver failed:%w", err) 58 | } 59 | if ver != socks5Ver { 60 | return fmt.Errorf("not supported ver:%v", ver) 61 | } 62 | methodSize, err := reader.ReadByte() 63 | if err != nil { 64 | return fmt.Errorf("read methodSize failed:%w", err) 65 | } 66 | method := make([]byte, methodSize) 67 | _, err = io.ReadFull(reader, method) 68 | if err != nil { 69 | return fmt.Errorf("read method failed:%w", err) 70 | } 71 | log.Println("ver", ver, "method", method) 72 | // +----+--------+ 73 | // |VER | METHOD | 74 | // +----+--------+ 75 | // | 1 | 1 | 76 | // +----+--------+ 77 | _, err = conn.Write([]byte{socks5Ver, 0x00}) 78 | if err != nil { 79 | return fmt.Errorf("write failed:%w", err) 80 | } 81 | return nil 82 | } 83 | -------------------------------------------------------------------------------- /proxy/v3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "encoding/binary" 6 | "errors" 7 | "fmt" 8 | "io" 9 | "log" 10 | "net" 11 | ) 12 | 13 | const socks5Ver = 0x05 14 | const cmdBind = 0x01 15 | const atypeIPV4 = 0x01 16 | const atypeHOST = 0x03 17 | const atypeIPV6 = 0x04 18 | 19 | func main() { 20 | server, err := net.Listen("tcp", "127.0.0.1:1080") 21 | if err != nil { 22 | panic(err) 23 | } 24 | for { 25 | client, err := server.Accept() 26 | if err != nil { 27 | log.Printf("Accept failed %v", err) 28 | continue 29 | } 30 | go process(client) 31 | } 32 | } 33 | 34 | func process(conn net.Conn) { 35 | defer conn.Close() 36 | reader := bufio.NewReader(conn) 37 | err := auth(reader, conn) 38 | if err != nil { 39 | log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err) 40 | return 41 | } 42 | err = connect(reader, conn) 43 | if err != nil { 44 | log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err) 45 | return 46 | } 47 | } 48 | 49 | func auth(reader *bufio.Reader, conn net.Conn) (err error) { 50 | // +----+----------+----------+ 51 | // |VER | NMETHODS | METHODS | 52 | // +----+----------+----------+ 53 | // | 1 | 1 | 1 to 255 | 54 | // +----+----------+----------+ 55 | // VER: 协议版本,socks5为0x05 56 | // NMETHODS: 支持认证的方法数量 57 | // METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。RFC预定义了一些值的含义,内容如下: 58 | // X’00’ NO AUTHENTICATION REQUIRED 59 | // X’02’ USERNAME/PASSWORD 60 | 61 | ver, err := reader.ReadByte() 62 | if err != nil { 63 | return fmt.Errorf("read ver failed:%w", err) 64 | } 65 | if ver != socks5Ver { 66 | return fmt.Errorf("not supported ver:%v", ver) 67 | } 68 | methodSize, err := reader.ReadByte() 69 | if err != nil { 70 | return fmt.Errorf("read methodSize failed:%w", err) 71 | } 72 | method := make([]byte, methodSize) 73 | _, err = io.ReadFull(reader, method) 74 | if err != nil { 75 | return fmt.Errorf("read method failed:%w", err) 76 | } 77 | 78 | // +----+--------+ 79 | // |VER | METHOD | 80 | // +----+--------+ 81 | // | 1 | 1 | 82 | // +----+--------+ 83 | _, err = conn.Write([]byte{socks5Ver, 0x00}) 84 | if err != nil { 85 | return fmt.Errorf("write failed:%w", err) 86 | } 87 | return nil 88 | } 89 | 90 | func connect(reader *bufio.Reader, conn net.Conn) (err error) { 91 | // +----+-----+-------+------+----------+----------+ 92 | // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | 93 | // +----+-----+-------+------+----------+----------+ 94 | // | 1 | 1 | X'00' | 1 | Variable | 2 | 95 | // +----+-----+-------+------+----------+----------+ 96 | // VER 版本号,socks5的值为0x05 97 | // CMD 0x01表示CONNECT请求 98 | // RSV 保留字段,值为0x00 99 | // ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型。 100 | // 0x01表示IPv4地址,DST.ADDR为4个字节 101 | // 0x03表示域名,DST.ADDR是一个可变长度的域名 102 | // DST.ADDR 一个可变长度的值 103 | // DST.PORT 目标端口,固定2个字节 104 | 105 | buf := make([]byte, 4) 106 | _, err = io.ReadFull(reader, buf) 107 | if err != nil { 108 | return fmt.Errorf("read header failed:%w", err) 109 | } 110 | ver, cmd, atyp := buf[0], buf[1], buf[3] 111 | if ver != socks5Ver { 112 | return fmt.Errorf("not supported ver:%v", ver) 113 | } 114 | if cmd != cmdBind { 115 | return fmt.Errorf("not supported cmd:%v", cmd) 116 | } 117 | addr := "" 118 | switch atyp { 119 | case atypeIPV4: 120 | _, err = io.ReadFull(reader, buf) 121 | if err != nil { 122 | return fmt.Errorf("read atyp failed:%w", err) 123 | } 124 | addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]) 125 | case atypeHOST: 126 | hostSize, err := reader.ReadByte() 127 | if err != nil { 128 | return fmt.Errorf("read hostSize failed:%w", err) 129 | } 130 | host := make([]byte, hostSize) 131 | _, err = io.ReadFull(reader, host) 132 | if err != nil { 133 | return fmt.Errorf("read host failed:%w", err) 134 | } 135 | addr = string(host) 136 | case atypeIPV6: 137 | return errors.New("IPv6: no supported yet") 138 | default: 139 | return errors.New("invalid atyp") 140 | } 141 | _, err = io.ReadFull(reader, buf[:2]) 142 | if err != nil { 143 | return fmt.Errorf("read port failed:%w", err) 144 | } 145 | port := binary.BigEndian.Uint16(buf[:2]) 146 | 147 | log.Println("dial", addr, port) 148 | 149 | // +----+-----+-------+------+----------+----------+ 150 | // |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | 151 | // +----+-----+-------+------+----------+----------+ 152 | // | 1 | 1 | X'00' | 1 | Variable | 2 | 153 | // +----+-----+-------+------+----------+----------+ 154 | // VER socks版本,这里为0x05 155 | // REP Relay field,内容取值如下 X’00’ succeeded 156 | // RSV 保留字段 157 | // ATYPE 地址类型 158 | // BND.ADDR 服务绑定的地址 159 | // BND.PORT 服务绑定的端口DST.PORT 160 | _, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0}) 161 | if err != nil { 162 | return fmt.Errorf("write failed: %w", err) 163 | } 164 | return nil 165 | } 166 | -------------------------------------------------------------------------------- /proxy/v4/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "context" 6 | "encoding/binary" 7 | "errors" 8 | "fmt" 9 | "io" 10 | "log" 11 | "net" 12 | ) 13 | 14 | const socks5Ver = 0x05 15 | const cmdBind = 0x01 16 | const atypeIPV4 = 0x01 17 | const atypeHOST = 0x03 18 | const atypeIPV6 = 0x04 19 | 20 | func main() { 21 | server, err := net.Listen("tcp", "127.0.0.1:1080") 22 | if err != nil { 23 | panic(err) 24 | } 25 | for { 26 | client, err := server.Accept() 27 | if err != nil { 28 | log.Printf("Accept failed %v", err) 29 | continue 30 | } 31 | go process(client) 32 | } 33 | } 34 | 35 | func process(conn net.Conn) { 36 | defer conn.Close() 37 | reader := bufio.NewReader(conn) 38 | err := auth(reader, conn) 39 | if err != nil { 40 | log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err) 41 | return 42 | } 43 | err = connect(reader, conn) 44 | if err != nil { 45 | log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err) 46 | return 47 | } 48 | } 49 | 50 | func auth(reader *bufio.Reader, conn net.Conn) (err error) { 51 | // +----+----------+----------+ 52 | // |VER | NMETHODS | METHODS | 53 | // +----+----------+----------+ 54 | // | 1 | 1 | 1 to 255 | 55 | // +----+----------+----------+ 56 | // VER: 协议版本,socks5为0x05 57 | // NMETHODS: 支持认证的方法数量 58 | // METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。RFC预定义了一些值的含义,内容如下: 59 | // X’00’ NO AUTHENTICATION REQUIRED 60 | // X’02’ USERNAME/PASSWORD 61 | 62 | ver, err := reader.ReadByte() 63 | if err != nil { 64 | return fmt.Errorf("read ver failed:%w", err) 65 | } 66 | if ver != socks5Ver { 67 | return fmt.Errorf("not supported ver:%v", ver) 68 | } 69 | methodSize, err := reader.ReadByte() 70 | if err != nil { 71 | return fmt.Errorf("read methodSize failed:%w", err) 72 | } 73 | method := make([]byte, methodSize) 74 | _, err = io.ReadFull(reader, method) 75 | if err != nil { 76 | return fmt.Errorf("read method failed:%w", err) 77 | } 78 | 79 | // +----+--------+ 80 | // |VER | METHOD | 81 | // +----+--------+ 82 | // | 1 | 1 | 83 | // +----+--------+ 84 | _, err = conn.Write([]byte{socks5Ver, 0x00}) 85 | if err != nil { 86 | return fmt.Errorf("write failed:%w", err) 87 | } 88 | return nil 89 | } 90 | 91 | func connect(reader *bufio.Reader, conn net.Conn) (err error) { 92 | // +----+-----+-------+------+----------+----------+ 93 | // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | 94 | // +----+-----+-------+------+----------+----------+ 95 | // | 1 | 1 | X'00' | 1 | Variable | 2 | 96 | // +----+-----+-------+------+----------+----------+ 97 | // VER 版本号,socks5的值为0x05 98 | // CMD 0x01表示CONNECT请求 99 | // RSV 保留字段,值为0x00 100 | // ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型。 101 | // 0x01表示IPv4地址,DST.ADDR为4个字节 102 | // 0x03表示域名,DST.ADDR是一个可变长度的域名 103 | // DST.ADDR 一个可变长度的值 104 | // DST.PORT 目标端口,固定2个字节 105 | 106 | buf := make([]byte, 4) 107 | _, err = io.ReadFull(reader, buf) 108 | if err != nil { 109 | return fmt.Errorf("read header failed:%w", err) 110 | } 111 | ver, cmd, atyp := buf[0], buf[1], buf[3] 112 | if ver != socks5Ver { 113 | return fmt.Errorf("not supported ver:%v", ver) 114 | } 115 | if cmd != cmdBind { 116 | return fmt.Errorf("not supported cmd:%v", cmd) 117 | } 118 | addr := "" 119 | switch atyp { 120 | case atypeIPV4: 121 | _, err = io.ReadFull(reader, buf) 122 | if err != nil { 123 | return fmt.Errorf("read atyp failed:%w", err) 124 | } 125 | addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]) 126 | case atypeHOST: 127 | hostSize, err := reader.ReadByte() 128 | if err != nil { 129 | return fmt.Errorf("read hostSize failed:%w", err) 130 | } 131 | host := make([]byte, hostSize) 132 | _, err = io.ReadFull(reader, host) 133 | if err != nil { 134 | return fmt.Errorf("read host failed:%w", err) 135 | } 136 | addr = string(host) 137 | case atypeIPV6: 138 | return errors.New("IPv6: no supported yet") 139 | default: 140 | return errors.New("invalid atyp") 141 | } 142 | _, err = io.ReadFull(reader, buf[:2]) 143 | if err != nil { 144 | return fmt.Errorf("read port failed:%w", err) 145 | } 146 | port := binary.BigEndian.Uint16(buf[:2]) 147 | 148 | dest, err := net.Dial("tcp", fmt.Sprintf("%v:%v", addr, port)) 149 | if err != nil { 150 | return fmt.Errorf("dial dst failed:%w", err) 151 | } 152 | defer dest.Close() 153 | log.Println("dial", addr, port) 154 | 155 | // +----+-----+-------+------+----------+----------+ 156 | // |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | 157 | // +----+-----+-------+------+----------+----------+ 158 | // | 1 | 1 | X'00' | 1 | Variable | 2 | 159 | // +----+-----+-------+------+----------+----------+ 160 | // VER socks版本,这里为0x05 161 | // REP Relay field,内容取值如下 X’00’ succeeded 162 | // RSV 保留字段 163 | // ATYPE 地址类型 164 | // BND.ADDR 服务绑定的地址 165 | // BND.PORT 服务绑定的端口DST.PORT 166 | _, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0}) 167 | if err != nil { 168 | return fmt.Errorf("write failed: %w", err) 169 | } 170 | ctx, cancel := context.WithCancel(context.Background()) 171 | defer cancel() 172 | 173 | go func() { 174 | _, _ = io.Copy(dest, reader) 175 | cancel() 176 | }() 177 | go func() { 178 | _, _ = io.Copy(conn, dest) 179 | cancel() 180 | }() 181 | 182 | <-ctx.Done() 183 | return nil 184 | } 185 | -------------------------------------------------------------------------------- /simpledict/v1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "net/http" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | client := &http.Client{} 13 | var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`) 14 | req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data) 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | req.Header.Set("Connection", "keep-alive") 19 | req.Header.Set("DNT", "1") 20 | req.Header.Set("os-version", "") 21 | req.Header.Set("sec-ch-ua-mobile", "?0") 22 | req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36") 23 | req.Header.Set("app-name", "xy") 24 | req.Header.Set("Content-Type", "application/json;charset=UTF-8") 25 | req.Header.Set("Accept", "application/json, text/plain, */*") 26 | req.Header.Set("device-id", "") 27 | req.Header.Set("os-type", "web") 28 | req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi") 29 | req.Header.Set("Origin", "https://fanyi.caiyunapp.com") 30 | req.Header.Set("Sec-Fetch-Site", "cross-site") 31 | req.Header.Set("Sec-Fetch-Mode", "cors") 32 | req.Header.Set("Sec-Fetch-Dest", "empty") 33 | req.Header.Set("Referer", "https://fanyi.caiyunapp.com/") 34 | req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9") 35 | req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872") 36 | resp, err := client.Do(req) 37 | if err != nil { 38 | log.Fatal(err) 39 | } 40 | defer resp.Body.Close() 41 | bodyText, err := ioutil.ReadAll(resp.Body) 42 | if err != nil { 43 | log.Fatal(err) 44 | } 45 | fmt.Printf("%s\n", bodyText) 46 | } 47 | -------------------------------------------------------------------------------- /simpledict/v2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | ) 11 | 12 | type DictRequest struct { 13 | TransType string `json:"trans_type"` 14 | Source string `json:"source"` 15 | UserID string `json:"user_id"` 16 | } 17 | 18 | func main() { 19 | client := &http.Client{} 20 | request := DictRequest{TransType: "en2zh", Source: "good"} 21 | buf, err := json.Marshal(request) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | var data = bytes.NewReader(buf) 26 | req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | req.Header.Set("Connection", "keep-alive") 31 | req.Header.Set("DNT", "1") 32 | req.Header.Set("os-version", "") 33 | req.Header.Set("sec-ch-ua-mobile", "?0") 34 | req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36") 35 | req.Header.Set("app-name", "xy") 36 | req.Header.Set("Content-Type", "application/json;charset=UTF-8") 37 | req.Header.Set("Accept", "application/json, text/plain, */*") 38 | req.Header.Set("device-id", "") 39 | req.Header.Set("os-type", "web") 40 | req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi") 41 | req.Header.Set("Origin", "https://fanyi.caiyunapp.com") 42 | req.Header.Set("Sec-Fetch-Site", "cross-site") 43 | req.Header.Set("Sec-Fetch-Mode", "cors") 44 | req.Header.Set("Sec-Fetch-Dest", "empty") 45 | req.Header.Set("Referer", "https://fanyi.caiyunapp.com/") 46 | req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9") 47 | req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872") 48 | resp, err := client.Do(req) 49 | if err != nil { 50 | log.Fatal(err) 51 | } 52 | defer resp.Body.Close() 53 | bodyText, err := ioutil.ReadAll(resp.Body) 54 | if err != nil { 55 | log.Fatal(err) 56 | } 57 | fmt.Printf("%s\n", bodyText) 58 | } 59 | -------------------------------------------------------------------------------- /simpledict/v3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | ) 11 | 12 | type DictRequest struct { 13 | TransType string `json:"trans_type"` 14 | Source string `json:"source"` 15 | UserID string `json:"user_id"` 16 | } 17 | 18 | type DictResponse struct { 19 | Rc int `json:"rc"` 20 | Wiki struct { 21 | KnownInLaguages int `json:"known_in_laguages"` 22 | Description struct { 23 | Source string `json:"source"` 24 | Target interface{} `json:"target"` 25 | } `json:"description"` 26 | ID string `json:"id"` 27 | Item struct { 28 | Source string `json:"source"` 29 | Target string `json:"target"` 30 | } `json:"item"` 31 | ImageURL string `json:"image_url"` 32 | IsSubject string `json:"is_subject"` 33 | Sitelink string `json:"sitelink"` 34 | } `json:"wiki"` 35 | Dictionary struct { 36 | Prons struct { 37 | EnUs string `json:"en-us"` 38 | En string `json:"en"` 39 | } `json:"prons"` 40 | Explanations []string `json:"explanations"` 41 | Synonym []string `json:"synonym"` 42 | Antonym []string `json:"antonym"` 43 | WqxExample [][]string `json:"wqx_example"` 44 | Entry string `json:"entry"` 45 | Type string `json:"type"` 46 | Related []interface{} `json:"related"` 47 | Source string `json:"source"` 48 | } `json:"dictionary"` 49 | } 50 | 51 | func main() { 52 | client := &http.Client{} 53 | request := DictRequest{TransType: "en2zh", Source: "good"} 54 | buf, err := json.Marshal(request) 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | var data = bytes.NewReader(buf) 59 | req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data) 60 | if err != nil { 61 | log.Fatal(err) 62 | } 63 | req.Header.Set("Connection", "keep-alive") 64 | req.Header.Set("DNT", "1") 65 | req.Header.Set("os-version", "") 66 | req.Header.Set("sec-ch-ua-mobile", "?0") 67 | req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36") 68 | req.Header.Set("app-name", "xy") 69 | req.Header.Set("Content-Type", "application/json;charset=UTF-8") 70 | req.Header.Set("Accept", "application/json, text/plain, */*") 71 | req.Header.Set("device-id", "") 72 | req.Header.Set("os-type", "web") 73 | req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi") 74 | req.Header.Set("Origin", "https://fanyi.caiyunapp.com") 75 | req.Header.Set("Sec-Fetch-Site", "cross-site") 76 | req.Header.Set("Sec-Fetch-Mode", "cors") 77 | req.Header.Set("Sec-Fetch-Dest", "empty") 78 | req.Header.Set("Referer", "https://fanyi.caiyunapp.com/") 79 | req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9") 80 | req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872") 81 | resp, err := client.Do(req) 82 | if err != nil { 83 | log.Fatal(err) 84 | } 85 | defer resp.Body.Close() 86 | bodyText, err := ioutil.ReadAll(resp.Body) 87 | if err != nil { 88 | log.Fatal(err) 89 | } 90 | var dictResponse DictResponse 91 | err = json.Unmarshal(bodyText, &dictResponse) 92 | if err != nil { 93 | log.Fatal(err) 94 | } 95 | fmt.Printf("%#v\n", dictResponse) 96 | } 97 | -------------------------------------------------------------------------------- /simpledict/v4/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | "os" 11 | ) 12 | 13 | type DictRequest struct { 14 | TransType string `json:"trans_type"` 15 | Source string `json:"source"` 16 | UserID string `json:"user_id"` 17 | } 18 | 19 | type DictResponse struct { 20 | Rc int `json:"rc"` 21 | Wiki struct { 22 | KnownInLaguages int `json:"known_in_laguages"` 23 | Description struct { 24 | Source string `json:"source"` 25 | Target interface{} `json:"target"` 26 | } `json:"description"` 27 | ID string `json:"id"` 28 | Item struct { 29 | Source string `json:"source"` 30 | Target string `json:"target"` 31 | } `json:"item"` 32 | ImageURL string `json:"image_url"` 33 | IsSubject string `json:"is_subject"` 34 | Sitelink string `json:"sitelink"` 35 | } `json:"wiki"` 36 | Dictionary struct { 37 | Prons struct { 38 | EnUs string `json:"en-us"` 39 | En string `json:"en"` 40 | } `json:"prons"` 41 | Explanations []string `json:"explanations"` 42 | Synonym []string `json:"synonym"` 43 | Antonym []string `json:"antonym"` 44 | WqxExample [][]string `json:"wqx_example"` 45 | Entry string `json:"entry"` 46 | Type string `json:"type"` 47 | Related []interface{} `json:"related"` 48 | Source string `json:"source"` 49 | } `json:"dictionary"` 50 | } 51 | 52 | func query(word string) { 53 | client := &http.Client{} 54 | request := DictRequest{TransType: "en2zh", Source: word} 55 | buf, err := json.Marshal(request) 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | var data = bytes.NewReader(buf) 60 | req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data) 61 | if err != nil { 62 | log.Fatal(err) 63 | } 64 | req.Header.Set("Connection", "keep-alive") 65 | req.Header.Set("DNT", "1") 66 | req.Header.Set("os-version", "") 67 | req.Header.Set("sec-ch-ua-mobile", "?0") 68 | req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36") 69 | req.Header.Set("app-name", "xy") 70 | req.Header.Set("Content-Type", "application/json;charset=UTF-8") 71 | req.Header.Set("Accept", "application/json, text/plain, */*") 72 | req.Header.Set("device-id", "") 73 | req.Header.Set("os-type", "web") 74 | req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi") 75 | req.Header.Set("Origin", "https://fanyi.caiyunapp.com") 76 | req.Header.Set("Sec-Fetch-Site", "cross-site") 77 | req.Header.Set("Sec-Fetch-Mode", "cors") 78 | req.Header.Set("Sec-Fetch-Dest", "empty") 79 | req.Header.Set("Referer", "https://fanyi.caiyunapp.com/") 80 | req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9") 81 | req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872") 82 | resp, err := client.Do(req) 83 | if err != nil { 84 | log.Fatal(err) 85 | } 86 | defer resp.Body.Close() 87 | bodyText, err := ioutil.ReadAll(resp.Body) 88 | if err != nil { 89 | log.Fatal(err) 90 | } 91 | if resp.StatusCode != 200 { 92 | log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText)) 93 | } 94 | var dictResponse DictResponse 95 | err = json.Unmarshal(bodyText, &dictResponse) 96 | if err != nil { 97 | log.Fatal(err) 98 | } 99 | fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs) 100 | for _, item := range dictResponse.Dictionary.Explanations { 101 | fmt.Println(item) 102 | } 103 | } 104 | 105 | func main() { 106 | if len(os.Args) != 2 { 107 | fmt.Fprintf(os.Stderr, `usage: simpleDict WORD 108 | example: simpleDict hello 109 | `) 110 | os.Exit(1) 111 | } 112 | word := os.Args[1] 113 | query(word) 114 | } 115 | --------------------------------------------------------------------------------