Spaces:
Sleeping
Sleeping
| package node | |
| import ( | |
| "errors" | |
| "fmt" | |
| "strconv" | |
| "strings" | |
| ) | |
| func CallSSRURL() { | |
| ssr := new(Ssr) | |
| ssr.Server = "xx.com" | |
| ssr.Port = 443 | |
| ssr.Protocol = "auth_aes128_md5" | |
| ssr.Method = "aes-256-cfb" | |
| ssr.Obfs = "tls1.2_ticket_auth" | |
| ssr.Password = "123456" | |
| ssr.Qurey = Ssrquery{ | |
| Obfsparam: "", | |
| Remarks: "没有名字", | |
| } | |
| cc := EncodeSSRURL(*ssr) | |
| fmt.Println(cc) | |
| } | |
| // ssr格式编码输出 | |
| func EncodeSSRURL(s Ssr) string { | |
| /*编码格式 | |
| ssr://base64(host:port:protocol:method:obfs:base64(password)/?obfsparam=base64(obfsparam)&protoparam=base64(protoparam)&remarks=base64(remarks)&group=base64(group)) | |
| */ | |
| obfsparam := "obfsparam=" + Base64Encode(s.Qurey.Obfsparam) | |
| remarks := "remarks=" + Base64Encode(s.Qurey.Remarks) | |
| // 如果没有备注默认使用服务器+端口作为备注 | |
| if s.Qurey.Remarks == "" { | |
| server_port := Base64Encode(s.Server + ":" + strconv.Itoa(s.Port)) | |
| remarks = fmt.Sprintf("remarks=%s", server_port) | |
| } | |
| param := fmt.Sprintf("%s:%d:%s:%s:%s:%s/?%s&%s", | |
| s.Server, | |
| s.Port, | |
| s.Protocol, | |
| s.Method, | |
| s.Obfs, | |
| Base64Encode(s.Password), | |
| obfsparam, | |
| remarks, | |
| ) | |
| return "ssr://" + Base64Encode(param) | |
| } | |
| // ssr解码 | |
| func DecodeSSRURL(s string) (Ssr, error) { | |
| /*解析格式 | |
| ssr://base64(host:port:protocol:method:obfs:base64(password)/?obfsparam=base64(obfsparam)&protoparam=base64(protoparam)&remarks=base64(remarks)&group=base64(group)) | |
| */ | |
| // 处理url链接中的base64编码 | |
| parts := strings.SplitN(s, "ssr://", 2) | |
| if len(parts) != 2 { | |
| return Ssr{}, errors.New("invalid SSR URL") | |
| } | |
| s = parts[0] + Base64Decode(parts[1]) | |
| // 检查是否包含"/?" 如果有就是有备注信息 | |
| var remarks, obfsparam string | |
| if strings.Contains(s, "/?") { | |
| // 解析备注信息 | |
| query := strings.Split(s, "/?")[1] | |
| s = strings.Replace(s, "/?"+query, "", 1) | |
| paramMap := make(map[string]string) | |
| if strings.Contains(query, "&") { | |
| params := strings.Split(query, "&") | |
| for _, param := range params { | |
| parts := strings.SplitN(param, "=", 2) | |
| if len(parts) != 2 { | |
| fmt.Println("Invalid parameter: ", param) | |
| continue | |
| } | |
| paramMap[parts[0]] = parts[1] | |
| } | |
| } else { | |
| q := strings.Split(query, "=") | |
| paramMap[q[0]] = q[1] | |
| } | |
| remarks = Base64Decode(paramMap["remarks"]) | |
| obfsparam = Base64Decode(paramMap["obfsparam"]) | |
| defer func() { | |
| if CheckEnvironment() { | |
| fmt.Println("remarks", remarks) | |
| fmt.Println("obfsparam", obfsparam) | |
| } | |
| }() | |
| } | |
| // 反着解析参数 怕有ipv6地址冒号混淆 | |
| param := strings.Split(s, ":") | |
| if len(param) < 6 { | |
| return Ssr{}, errors.New("长度没有6") | |
| } | |
| password := param[len(param)-1] | |
| obfs := param[len(param)-2] | |
| method := param[len(param)-3] | |
| protocol := param[len(param)-4] | |
| port, _ := strconv.Atoi(param[len(param)-5]) | |
| server := ValRetIPv6Addr(param[len(param)-6]) | |
| // 如果没有备注默认使用服务器+端口作为备注 | |
| if remarks == "" { | |
| remarks = server + ":" + strconv.Itoa(port) | |
| } | |
| if CheckEnvironment() { | |
| fmt.Println("password", password) | |
| fmt.Println("obfs", obfs) | |
| fmt.Println("method", method) | |
| fmt.Println("protocol", protocol) | |
| fmt.Println("port", port) | |
| fmt.Println("server", server) | |
| } | |
| return Ssr{ | |
| Server: server, | |
| Port: port, | |
| Protocol: protocol, | |
| Method: method, | |
| Obfs: obfs, | |
| Password: password, | |
| Qurey: Ssrquery{ | |
| Obfsparam: obfsparam, | |
| Remarks: remarks, | |
| }, | |
| Type: "ssr", | |
| }, nil | |
| } | |
| type Ssr struct { | |
| Server string | |
| Port int | |
| Protocol string | |
| Method string | |
| Obfs string | |
| Password string | |
| Qurey Ssrquery | |
| Type string | |
| } | |
| type Ssrquery struct { | |
| Obfsparam string | |
| Remarks string | |
| } | |