sublinker / node /ssr.go
YimoEx
init
bb9df9e
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
}