package algos import ( "fmt" "net/url" "regexp" "strconv" "sync" "time" ) // getTimestamp 获取时间戳(辅助函数) func getTimestamp(unix *int64) int64 { if unix == nil { return time.Now().Unix() } return *unix } // Sign2 签名方法2(Gorgon 或 8404) func Sign2( params string, xSSStub string, secDeviceID string, cookie string, aid int, licenseID int, sdkVersionStr string, sdkVersion int, platform int, unix *int64, ) map[string]string { timestamp := getTimestamp(unix) // 根据当前算法选择生成签名 currentAlgo := GlobalAlgorithmSwitcher.GetCurrentAlgorithm() if currentAlgo == "8404" { algo := NewAlgo8404(params, timestamp, xSSStub) return algo.GetValue() } // 默认使用 Gorgon gorgon := NewGorgon(params, timestamp, xSSStub, cookie) return gorgon.GetValue() } // Sign4 签名方法4(Gorgon + Ladon + Argus) func Sign4( params string, xSSStub string, secDeviceID string, cookie string, aid int, licenseID int, sdkVersionStr string, sdkVersion int, platform int, unix *int64, ) map[string]string { timestamp := getTimestamp(unix) // 根据当前算法选择生成基础签名 var result map[string]string currentAlgo := GlobalAlgorithmSwitcher.GetCurrentAlgorithm() if currentAlgo == "8404" { algo := NewAlgo8404(params, timestamp, xSSStub) result = algo.GetValue() } else { // 默认使用 Gorgon gorgon := NewGorgon(params, timestamp, xSSStub, cookie) result = gorgon.GetValue() } // 添加 Ladon 和 Argus 签名 ladon := &Ladon{} result["x-ladon"] = ladon.Encrypt(timestamp, licenseID, aid) result["x-helios"] = result["x-ladon"] // X-Helios 与 X-Ladon 同值(对齐书源实现) argus := &Argus{} result["x-argus"] = argus.GetSign( params, xSSStub, timestamp, aid, licenseID, platform, secDeviceID, sdkVersionStr, sdkVersion, ) return result } // SignatureInterface 签名接口 type SignatureInterface interface { Sign(params, xSSStub, secDeviceID, cookie string, aid, licenseID int, sdkVersionStr string, sdkVersion, platform int, unix *int64) map[string]string } // SignatureSwitcher 签名方法切换器 type SignatureSwitcher struct { mu sync.RWMutex currentMethod string methods map[string]SignatureInterface } // NewSignatureSwitcher 创建签名切换器 func NewSignatureSwitcher() *SignatureSwitcher { switcher := &SignatureSwitcher{ methods: make(map[string]SignatureInterface), } // 注册所有签名方法 switcher.methods["sign2"] = &Sign2Method{} switcher.methods["sign4"] = &Sign4Method{} // 设置默认签名方法为sign2 switcher.currentMethod = "sign2" return switcher } // SwitchSignature 切换签名方法 func (s *SignatureSwitcher) SwitchSignature(method string) error { s.mu.Lock() defer s.mu.Unlock() if _, exists := s.methods[method]; !exists { return fmt.Errorf("不支持的签名方法: %s", method) } s.currentMethod = method return nil } // GetCurrentMethod 获取当前签名方法 func (s *SignatureSwitcher) GetCurrentMethod() string { s.mu.RLock() defer s.mu.RUnlock() return s.currentMethod } // Sign 使用当前签名方法进行签名 func (s *SignatureSwitcher) Sign(urlStr string, headers map[string]string) map[string]string { return SignFromURL(s.GetCurrentMethod(), urlStr, headers) } // SignFromParams 使用当前签名方法进行签名 func (s *SignatureSwitcher) SignFromParams(params, xSSStub, secDeviceID, cookie string, aid, licenseID int, sdkVersionStr string, sdkVersion, platform int, unix *int64) map[string]string { s.mu.RLock() method := s.methods[s.currentMethod] s.mu.RUnlock() return method.Sign(params, xSSStub, secDeviceID, cookie, aid, licenseID, sdkVersionStr, sdkVersion, platform, unix) } // Sign2Method Sign2签名方法实现 type Sign2Method struct{} func (s *Sign2Method) Sign(params, xSSStub, secDeviceID, cookie string, aid, licenseID int, sdkVersionStr string, sdkVersion, platform int, unix *int64) map[string]string { return Sign2(params, xSSStub, secDeviceID, cookie, aid, licenseID, sdkVersionStr, sdkVersion, platform, unix) } // Sign4Method Sign4签名方法实现 type Sign4Method struct{} func (s *Sign4Method) Sign(params, xSSStub, secDeviceID, cookie string, aid, licenseID int, sdkVersionStr string, sdkVersion, platform int, unix *int64) map[string]string { return Sign4(params, xSSStub, secDeviceID, cookie, aid, licenseID, sdkVersionStr, sdkVersion, platform, unix) } // GlobalSignatureSwitcher 全局签名切换器实例 var GlobalSignatureSwitcher = NewSignatureSwitcher() // SignFromURL 从 URL 和 headers 中提取参数并生成签名 func SignFromURL(method, urlStr string, headers map[string]string) map[string]string { // 解析 URL u, err := url.Parse(urlStr) if err != nil { return make(map[string]string) } // 提取查询参数 params := u.RawQuery xSSStub := headers["x-ss-stub"] cookie := headers["Cookie"] // 从 URL 中提取 device_id 和 aid deviceIDRegex := regexp.MustCompile(`device_id=(\d+)`) aidRegex := regexp.MustCompile(`aid=(\d+)`) deviceIDMatch := deviceIDRegex.FindStringSubmatch(urlStr) aidMatch := aidRegex.FindStringSubmatch(urlStr) secDeviceID := "" aid := 1967 if len(deviceIDMatch) > 1 { secDeviceID = deviceIDMatch[1] } if len(aidMatch) > 1 { aid, _ = strconv.Atoi(aidMatch[1]) } // 使用固定参数 licenseID := 1611921764 sdkVersionStr := "v04.06.01-ml-android" sdkVersion := 135004672 platform := 0 // 根据方法调用对应的签名函数 if method == "sign4" { return Sign4(params, xSSStub, secDeviceID, cookie, aid, licenseID, sdkVersionStr, sdkVersion, platform, nil) } return Sign2(params, xSSStub, secDeviceID, cookie, aid, licenseID, sdkVersionStr, sdkVersion, platform, nil) } // Sign2Wrapper 硬编码使用 Sign2(从 URL 和 headers 生成签名) func Sign2Wrapper(urlStr string, headers map[string]string) map[string]string { return SignFromURL("sign2", urlStr, headers) }