🔧 chore: 初始化番茄小说 API 项目结构
新增项目基础框架,包含核心 API 实现、算法模块、HTTP 处理器等完整功能模块
This commit is contained in:
commit
6981148727
107 files changed
+12463
No files matched your search
@@ -0,0 +1,219 @@
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user