package node import ( "fmt" "net/url" "strconv" "strings" ) type VLESS struct { Name string `json:"name"` Uuid string `json:"uuid"` Server string `json:"server"` Port int `json:"port"` Query VLESSQuery `json:"query"` } type VLESSQuery struct { Security string `json:"security"` Alpn []string `json:"alpn"` Sni string `json:"sni"` Fp string `json:"fp"` Sid string `json:"sid"` Pbk string `json:"pbk"` Flow string `json:"flow"` Encryption string `json:"encryption"` Type string `json:"type"` HeaderType string `json:"headerType"` Path string `json:"path"` Host string `json:"host"` } func CallVLESS() { vless := VLESS{ Name: "Sharon-香港", Uuid: "6adb4f43-9813-45f4-abf8-772be7db08sd", Server: "ss.com", Port: 443, Query: VLESSQuery{ Security: "reality", // Alpn: "", Sni: "ss.com", Fp: "chrome", Sid: "", Pbk: "g-oxbqigzCaXqARxuyD2_vbTYeMD9zn8wnTo02S69QM", Flow: "xtls-rprx-vision", Encryption: "none", Type: "tcp", HeaderType: "none", Path: "", Host: "", }, } fmt.Println(EncodeVLESSURL(vless)) } // vless编码 func EncodeVLESSURL(v VLESS) string { /* base64(username@host:port?encryption=none&security=auto&type=tcp) */ u := url.URL{ Scheme: "vless", User: url.User(v.Uuid), Host: fmt.Sprintf("%s:%d", v.Server, v.Port), } q := u.Query() q.Set("security", v.Query.Security) // q.Set("alpn", v.Query.Alpn) q.Set("sni", v.Query.Sni) q.Set("fp", v.Query.Fp) q.Set("sid", v.Query.Sid) q.Set("pbk", v.Query.Pbk) q.Set("flow", v.Query.Flow) q.Set("encryption", v.Query.Encryption) q.Set("type", v.Query.Type) q.Set("headerType", v.Query.HeaderType) q.Set("path", v.Query.Path) q.Set("host", v.Query.Host) u.Fragment = v.Name // 检查query是否有空值,有的话删除 for k, v := range q { if v[0] == "" { delete(q, k) // fmt.Printf("k: %v, v: %v\n", k, v) } } u.RawQuery = q.Encode() // 如果没有name则用服务器加端口 if v.Name != "" { u.Fragment = v.Server + ":" + strconv.Itoa(v.Port) } return u.String() } // vless解码 func DecodeVLESSURL(s string) (VLESS, error) { /* base64(username@host:port?encryption=none&security=auto&type=tcp) */ // 解析base64然后重新url编码 if !strings.Contains(s, "vless://") { return VLESS{}, fmt.Errorf("非vless协议: %s", s) } s = "vless://" + Base64Decode(strings.Split(s, "://")[1]) // 解析url u, err := url.Parse(s) if err != nil { return VLESS{}, fmt.Errorf("url parse error: %v", err) } uuid := u.User.Username() hostname := u.Hostname() port, _ := strconv.Atoi(u.Port()) encryption := u.Query().Get("encryption") security := u.Query().Get("security") types := u.Query().Get("type") flow := u.Query().Get("flow") headerType := u.Query().Get("headerType") pbk := u.Query().Get("pbk") sid := u.Query().Get("sid") fp := u.Query().Get("fp") alpns := u.Query().Get("alpn") alpn := strings.Split(alpns, ",") if alpns == "" { alpn = nil } sni := u.Query().Get("sni") path := u.Query().Get("path") host := u.Query().Get("host") // 如果没有设置name,则使用hostname:port name := u.Fragment if name == "" { name = hostname + ":" + u.Port() } if CheckEnvironment() { fmt.Println("uuid:", uuid) fmt.Println("hostname:", hostname) fmt.Println("port:", port) fmt.Println("encryption:", encryption) fmt.Println("security:", security) fmt.Println("type:", types) fmt.Println("flow:", flow) fmt.Println("headerType:", headerType) fmt.Println("pbk:", pbk) fmt.Println("sid:", sid) fmt.Println("fp:", fp) fmt.Println("alpn:", alpn) fmt.Println("sni:", sni) fmt.Println("path:", path) fmt.Println("host:", host) fmt.Println("name:", name) } return VLESS{ Name: name, Uuid: uuid, Server: hostname, Port: port, Query: VLESSQuery{ Security: security, Alpn: alpn, Sni: sni, Fp: fp, Sid: sid, Pbk: pbk, Flow: flow, Encryption: encryption, Type: types, HeaderType: headerType, Path: path, Host: host, }, }, nil }