🔧 chore: 初始化番茄小说 API 项目结构

新增项目基础框架,包含核心 API 实现、算法模块、HTTP 处理器等完整功能模块
This commit is contained in:
chenxin committed 2026-08-28 15:22:22 +08:00
commit 6981148727
107 files changed
+12463

No files matched your search

+174
View File
@@ -0,0 +1,174 @@
package algos
import (
"crypto/md5"
"encoding/hex"
"fmt"
"math/rand"
)
// Algo8404 8404加密器
type Algo8404 struct {
unix int64
params string
xSSStub string
}
// NewAlgo8404 创建新的Algo8404实例
func NewAlgo8404(params string, unix int64, xSSStub string) *Algo8404 {
if xSSStub == "" {
xSSStub = "00000000000000000000000000000000"
}
return &Algo8404{
unix: unix,
params: params,
xSSStub: xSSStub,
}
}
// getXGorgon 生成X-Gorgon签名
func (a *Algo8404) getXGorgon() string {
timeHex := fmt.Sprintf("%x", a.unix)
timeBin, _ := hex.DecodeString(timeHex)
m := md5.Sum([]byte(a.params))
mBytes := m[:4]
var aaa []byte
if a.xSSStub != "" {
stubBytes, _ := hex.DecodeString(a.xSSStub)
if len(stubBytes) >= 4 {
aaa = stubBytes[:4]
} else {
aaa = make([]byte, 4)
}
} else {
aaa = make([]byte, 4)
}
// 生成随机数
a1 := rand.Intn(256)
a2 := rand.Intn(256)
// 构建数据
data := make([]byte, 0)
data = append(data, mBytes...)
data = append(data, aaa...)
data = append(data, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x04}...)
data = append(data, timeBin...)
// 初始化表
table := make([]int, 256)
for i := 0; i < 256; i++ {
table[i] = i
}
key := []int{0x4A, 0x00, 0x16, a2, 0x47, 0x6C, 0x00, a1}
// 第一轮处理
w8 := 0
for i := 0; i < 256; i++ {
keyI := i & 7
w10 := key[keyI]
w9 := w8 + table[i]
w9 = (w9 + w10) & 0xFFFFFFFF
w10 = w9
w10 &= 0xFFFFFF00
w20 := (w9 - w10) & 0xFFFFFFFF
table[i] = table[w20]
w8 = w20
}
// 第二轮处理
dataArr := make([]int, len(data))
for i, b := range data {
dataArr[i] = int(b)
}
w26 := 0
for i := 0; i < len(dataArr); i++ {
w25 := i
w8_ := w25 ^ 1
w9_ := ((w25 & 1) << 1) & 2
w8_ = (w9_ + w8_) & 0xFFFFFFFF
x10 := w8_ & 0xFF
w9b := table[x10]
w11 := (w26 ^ w9b) & 0xFFFFFFFF
w9c := ((w26 | w9b) << 1) & 0xFFFFFFFF
w9c = (w9c - w11) & 0xFFFFFFFF
w26 = w9c
x11 := w26 & 0xFF
w12 := table[x11]
table[x10] = w12
table[x11] = w12
w10_ := w12
w11_ := dataArr[i]
w13_ := w10_ | w12
w10b := w10_ & w12
wX10 := (w13_ + w10b) & 0xFF
ks := table[wX10]
dataArr[i] = ks ^ w11_
}
// 第三轮处理
w2 := 0xFFFFFFAA
w3 := 0x55
w4 := 0x33
w8_2 := (^len(dataArr)) & 0xFFFFFFFF
for i := 0; i < len(dataArr); i++ {
val := dataArr[i]
w16 := ((val >> 4) & 0x0F) | ((val & 0x0F) << 4)
dataArr[i] = w16 & 0xFF
if i == len(dataArr)-1 {
dataArr[i] = dataArr[0] ^ w16
} else {
w7 := dataArr[i]
w16n := dataArr[i+1]
w20 := w7 | w16n
wI2 := w7 & w16n
dataArr[i] = (w20 - wI2) & 0xFF
}
w13_ := dataArr[i]
t1 := w2 & (w13_ << 1)
t2 := w3 & (w13_ >> 1)
w13_ = t1 | t2
t3 := w13_ << 2
t4 := w4 & (w13_ >> 2)
mix := (t3 & 0xFFFFFFCF) | t4
high := (mix >> 4) & 0x0F
low := mix & 0x0FFFFFFF
mix = ((low << 4) | high) & 0xFFFFFFFF
w13_ = mix ^ w8_2
dataArr[i] = w13_ & 0xFF
}
// 构建输出
output := make([]byte, 0)
output = append(output, 0x84, 0x04)
output = append(output, byte(a1), byte(a2))
output = append(output, 0x00, 0x00)
for _, val := range dataArr {
output = append(output, byte(val))
}
return hex.EncodeToString(output)
}
// GetValue 获取加密值
func (a *Algo8404) GetValue() map[string]string {
return map[string]string{
"X-Gorgon": a.getXGorgon(),
"X-Khronos": fmt.Sprintf("%d", a.unix),
"X-SS-REQ-Ticket": fmt.Sprintf("%d", a.unix*1000),
}
}
+177
View File
@@ -0,0 +1,177 @@
package algos
import (
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"fmt"
"math/rand"
"net/url"
)
// Argus Argus加密器
type Argus struct{}
// encryptEncPb 加密ProtoBuf
func encryptEncPb(data []byte, l int) []byte {
dataCopy := make([]byte, len(data))
copy(dataCopy, data)
xorArray := dataCopy[:8]
for i := 8; i < l; i++ {
dataCopy[i] ^= xorArray[i%8]
}
// 反转数组
for i := 0; i < l/2; i++ {
dataCopy[i], dataCopy[l-1-i] = dataCopy[l-1-i], dataCopy[i]
}
return dataCopy[:l]
}
// GetBodyHash 获取Body哈希
func GetBodyHash(stub string) []byte {
sm3 := NewSM3()
if stub == "" || len(stub) == 0 {
return sm3.Hash(make([]byte, 16))[0:6]
}
stubBytes, _ := hex.DecodeString(stub)
return sm3.Hash(stubBytes)[0:6]
}
// GetQueryHash 获取Query哈希
func GetQueryHash(query string) []byte {
sm3 := NewSM3()
if query == "" || len(query) == 0 {
return sm3.Hash(make([]byte, 16))[0:6]
}
return sm3.Hash([]byte(query))[0:6]
}
// Encrypt Argus加密
func (a *Argus) Encrypt(xargusBean map[int]interface{}) string {
// 创建ProtoBuf
protobuf := NewProtoBuf(xargusBean).ToBuf()
// PKCS7填充
protobuf = AddPKCS7Padding(protobuf, 16)
newLen := len(protobuf)
signKey := []byte{
0xAC, 0x1A, 0xDA, 0xAE, 0x95, 0xA7, 0xAF, 0x94,
0xA5, 0x11, 0x4A, 0xB3, 0xB3, 0xA9, 0x7D, 0xD8,
0x00, 0x50, 0xAA, 0x0A, 0x39, 0x31, 0x4C, 0x40,
0x52, 0x8C, 0xAE, 0xC9, 0x52, 0x56, 0xC2, 0x8C,
}
sm3Output := []byte{
0xFC, 0x78, 0xE0, 0xA9, 0x65, 0x7A, 0x0C, 0x74,
0x8C, 0xE5, 0x15, 0x59, 0x90, 0x3C, 0xCF, 0x03,
0x51, 0x0E, 0x51, 0xD3, 0xCF, 0xF2, 0x32, 0xD7,
0x13, 0x43, 0xE8, 0x8A, 0x32, 0x1C, 0x53, 0x04,
}
key := sm3Output[:32]
keyList := make([]uint64, 0)
encPb := make([]byte, newLen)
for i := 0; i < 2; i++ {
val1 := binary.LittleEndian.Uint64(key[i*16 : i*16+8])
val2 := binary.LittleEndian.Uint64(key[i*16+8 : i*16+16])
keyList = append(keyList, val1, val2)
}
for i := 0; i < newLen/16; i++ {
pt := []uint64{
binary.LittleEndian.Uint64(protobuf[i*16 : i*16+8]),
binary.LittleEndian.Uint64(protobuf[i*16+8 : i*16+16]),
}
ct := SimonEnc(pt, keyList, 0)
binary.LittleEndian.PutUint64(encPb[i*16:i*16+8], ct[0])
binary.LittleEndian.PutUint64(encPb[i*16+8:i*16+16], ct[1])
}
header := []byte{0xF2, 0xF7, 0xFC, 0xFF, 0xF2, 0xF7, 0xFC, 0xFF}
bBuffer := encryptEncPb(append(header, encPb...), newLen+8)
bBuffer = append([]byte{0xA6, 0x6E, 0xAD, 0x9F, 0x77, 0x01, 0xD0, 0x0C, 0x18}, bBuffer...)
bBuffer = append(bBuffer, []byte("ao")...)
// AES加密
keyHash := md5.Sum(signKey[:16])
ivHash := md5.Sum(signKey[16:])
block, _ := aes.NewCipher(keyHash[:])
paddedBuffer := AddPKCS7Padding(bBuffer, aes.BlockSize)
ciphertext := make([]byte, len(paddedBuffer))
mode := cipher.NewCBCEncrypter(block, ivHash[:])
mode.CryptBlocks(ciphertext, paddedBuffer)
result := append([]byte{0xF2, 0x81}, ciphertext...)
return base64.StdEncoding.EncodeToString(result)
}
// GetSign 获取签名
func (a *Argus) GetSign(
queryhash string,
data string,
timestamp int64,
aid int,
licenseID int,
platform int,
secDeviceID string,
sdkVersion string,
sdkVersionInt int,
) string {
paramsDict, _ := url.ParseQuery(queryhash)
deviceID := ""
if val, ok := paramsDict["device_id"]; ok && len(val) > 0 {
deviceID = val[0]
}
versionName := ""
if val, ok := paramsDict["version_name"]; ok && len(val) > 0 {
versionName = val[0]
}
xargusBean := map[int]interface{}{
1: 0x20200929 << 1,
2: 2,
3: rand.Int63n(0x7FFFFFFF),
4: fmt.Sprintf("%d", aid),
5: deviceID,
6: fmt.Sprintf("%d", licenseID),
7: versionName,
8: sdkVersion,
9: sdkVersionInt,
10: make([]byte, 8),
11: platform,
12: timestamp << 1,
13: GetBodyHash(data),
14: GetQueryHash(queryhash),
15: map[int]interface{}{
1: 1,
2: 1,
3: 1,
7: 3348294860,
},
16: secDeviceID,
20: "none",
21: 738,
23: map[int]interface{}{
1: "NX551J",
2: 8196,
4: 2162219008,
},
25: 2,
}
return a.Encrypt(xargusBean)
}
+53
View File
@@ -0,0 +1,53 @@
package algos
// ByteBuf 字节缓冲区
type ByteBuf struct {
mem []byte
dataSize int
pos int
}
// NewByteBuf 创建新的字节缓冲区
func NewByteBuf(data []byte, size *int) *ByteBuf {
buf := &ByteBuf{
pos: 0,
}
if data != nil {
buf.mem = data
}
if size != nil {
buf.dataSize = *size
} else if data != nil {
buf.dataSize = len(data)
} else {
panic("Either size or data must be provided")
}
return buf
}
// Data 获取数据
func (b *ByteBuf) Data() []byte {
return b.mem
}
// Size 获取大小
func (b *ByteBuf) Size() int {
return b.dataSize
}
// RemovePadding 移除填充
func (b *ByteBuf) RemovePadding() []byte {
paddingSize := PKCS7DataLength(b.mem, b.dataSize, 16)
if paddingSize == 0 {
return b.mem[:b.dataSize]
}
b.dataSize = paddingSize
dst := make([]byte, b.dataSize)
copy(dst, b.mem[:b.dataSize])
b.mem = dst
return b.mem
}
+137
View File
@@ -0,0 +1,137 @@
package algos
import (
"crypto/md5"
"encoding/hex"
"fmt"
"strconv"
)
// Gorgon Gorgon加密器
type Gorgon struct {
unix int64
params string
xSSStub string
cookies string
}
// NewGorgon 创建新的Gorgon实例
func NewGorgon(params string, unix int64, xSSStub string, cookies string) *Gorgon {
if xSSStub == "" {
xSSStub = "00000000000000000000000000000000"
}
return &Gorgon{
unix: unix,
params: params,
xSSStub: xSSStub,
cookies: cookies,
}
}
// hash MD5哈希
func (g *Gorgon) hash(data string) string {
hasher := md5.New()
hasher.Write([]byte(data))
return hex.EncodeToString(hasher.Sum(nil))
}
// getBaseString 获取基础字符串
func (g *Gorgon) getBaseString() string {
baseStr := g.hash(g.params)
baseStr = baseStr + g.xSSStub
if g.cookies != "" {
baseStr = baseStr + g.hash(g.cookies)
} else {
baseStr = baseStr + "00000000000000000000000000000000"
}
return baseStr
}
// rbitAlgorithm 位反转算法
func (g *Gorgon) rbitAlgorithm(num int) int {
result := ""
tmpString := fmt.Sprintf("%08b", num)
for i := 0; i < 8; i++ {
result = result + string(tmpString[7-i])
}
val, _ := strconv.ParseInt(result, 2, 64)
return int(val)
}
// hexString 转十六进制字符串
func (g *Gorgon) hexString(num int) string {
tmpString := fmt.Sprintf("%x", num)
if len(tmpString) < 2 {
tmpString = "0" + tmpString
}
return tmpString
}
// reverse 反转
func (g *Gorgon) reverse(num int) int {
tmpString := g.hexString(num)
val, _ := strconv.ParseInt(tmpString[1:]+tmpString[:1], 16, 64)
return int(val)
}
// encrypt 加密
func (g *Gorgon) encrypt(data string) map[string]string {
length := 0x14
key := []int{
0xDF, 0x77, 0xB9, 0x40, 0xB9, 0x9B, 0x84, 0x83,
0xD1, 0xB9, 0xCB, 0xD1, 0xF7, 0xC2, 0xB9, 0x85,
0xC3, 0xD0, 0xFB, 0xC3,
}
paramList := make([]int, 0)
for i := 0; i < 12; i += 4 {
temp := data[8*i : 8*(i+1)]
for j := 0; j < 4; j++ {
val, _ := strconv.ParseInt(temp[j*2:(j+1)*2], 16, 64)
paramList = append(paramList, int(val))
}
}
paramList = append(paramList, 0x0, 0x6, 0xB, 0x1C)
H := int(g.unix)
paramList = append(paramList, (H&0xFF000000)>>24)
paramList = append(paramList, (H&0x00FF0000)>>16)
paramList = append(paramList, (H&0x0000FF00)>>8)
paramList = append(paramList, (H&0x000000FF)>>0)
eorResultList := make([]int, len(paramList))
for i, val := range paramList {
eorResultList[i] = val ^ key[i]
}
for i := 0; i < length; i++ {
C := g.reverse(eorResultList[i])
D := eorResultList[(i+1)%length]
E := C ^ D
F := g.rbitAlgorithm(E)
H := ((F ^ 0xFFFFFFFF) ^ length) & 0xFF
eorResultList[i] = H
}
result := ""
for _, param := range eorResultList {
result += g.hexString(param)
}
return map[string]string{
"x-ss-req-ticket": strconv.FormatInt(g.unix*1000, 10),
"x-khronos": strconv.FormatInt(g.unix, 10),
"x-gorgon": fmt.Sprintf("0404b0d30000%s", result),
}
}
// GetValue 获取加密值
func (g *Gorgon) GetValue() map[string]string {
return g.encrypt(g.getBaseString())
}
+121
View File
@@ -0,0 +1,121 @@
package algos
import (
"crypto/md5"
"crypto/rand"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"fmt"
)
// validate 验证并限制在64位范围内
func validate(num uint64) uint64 {
return num & 0xFFFFFFFFFFFFFFFF
}
// ror 右循环移位
func ror(value uint64, count int) uint64 {
nbits := 64
count %= nbits
low := (value << (nbits - count))
value = (value >> count)
value = value | low
return value
}
// encryptLadonInput 加密Ladon输入
func encryptLadonInput(hashTable []byte, inputData []byte) []byte {
data0 := binary.LittleEndian.Uint64(inputData[:8])
data1 := binary.LittleEndian.Uint64(inputData[8:])
for i := 0; i < 0x22; i++ {
hash := binary.LittleEndian.Uint64(hashTable[i*8 : (i+1)*8])
data1 = validate(hash ^ (data0 + ((data1 >> 8) | (data1 << (64 - 8)))))
data0 = validate(data1 ^ ((data0 >> 0x3D) | (data0 << (64 - 0x3D))))
}
outputData := make([]byte, 26)
binary.LittleEndian.PutUint64(outputData[:8], data0)
binary.LittleEndian.PutUint64(outputData[8:], data1)
return outputData
}
// encryptLadon 加密Ladon
func encryptLadon(md5Hex []byte, data []byte, size int) []byte {
hashTable := make([]byte, 272+16)
copy(hashTable[:32], md5Hex)
temp := make([]uint64, 0)
for i := 0; i < 4; i++ {
temp = append(temp, binary.LittleEndian.Uint64(hashTable[i*8:(i+1)*8]))
}
bufferB0 := temp[0]
bufferB8 := temp[1]
temp = temp[2:]
for i := 0; i < 0x22; i++ {
x9 := bufferB0
x8 := bufferB8
x8 = validate(ror(x8, 8))
x8 = validate(x8 + x9)
x8 = validate(x8 ^ uint64(i))
temp = append(temp, x8)
x8 = validate(x8 ^ ror(x9, 61))
binary.LittleEndian.PutUint64(hashTable[(i+1)*8:], x8)
bufferB0 = x8
bufferB8 = temp[0]
temp = temp[1:]
}
newSize := PaddingSize(size)
input := make([]byte, newSize)
copy(input[:size], data)
PKCS7PadBuffer(input, size, newSize, 16)
output := make([]byte, newSize)
for i := 0; i < newSize/16; i++ {
result := encryptLadonInput(hashTable, input[i*16:(i+1)*16])
copy(output[i*16:(i+1)*16], result)
}
return output
}
// LadonEncrypt Ladon加密主函数
func LadonEncrypt(khronos int64, lcID int, aid int, randomBytes []byte) string {
data := fmt.Sprintf("%d-%d-%d", khronos, lcID, aid)
if randomBytes == nil {
randomBytes = make([]byte, 4)
rand.Read(randomBytes)
}
keygen := append(randomBytes, []byte(fmt.Sprintf("%d", aid))...)
hasher := md5.New()
hasher.Write(keygen)
md5Hex := hex.EncodeToString(hasher.Sum(nil))
size := len(data)
newSize := PaddingSize(size)
output := make([]byte, newSize+4)
copy(output[:4], randomBytes)
encrypted := encryptLadon([]byte(md5Hex), []byte(data), size)
copy(output[4:], encrypted)
return base64.StdEncoding.EncodeToString(output)
}
// Ladon Ladon加密器
type Ladon struct{}
// Encrypt Ladon加密
func (l *Ladon) Encrypt(xKhronos int64, lcID int, aid int) string {
return LadonEncrypt(xKhronos, lcID, aid, nil)
}
+78
View File
@@ -0,0 +1,78 @@
package algos
// PKCS7DataLength 获取PKCS7填充数据的实际长度
func PKCS7DataLength(buffer []byte, bufferSize, modulus int) int {
if bufferSize%modulus != 0 || bufferSize < modulus {
return 0
}
paddingValue := buffer[bufferSize-1]
if paddingValue < 1 || int(paddingValue) > modulus {
return 0
}
if bufferSize < int(paddingValue)+1 {
return 0
}
count := 1
bufferSize--
for i := count; i < int(paddingValue); i++ {
bufferSize--
if buffer[bufferSize] != paddingValue {
return 0
}
}
return bufferSize
}
// PKCS7PadBuffer 对缓冲区进行PKCS7填充
func PKCS7PadBuffer(buffer []byte, dataLength, bufferSize, modulus int) int {
padByte := modulus - (dataLength % modulus)
if dataLength+padByte > bufferSize {
return -padByte
}
for i := 0; i < padByte; i++ {
buffer[dataLength+i] = byte(padByte)
}
return padByte
}
// PaddingSize 计算填充后的大小
func PaddingSize(size int) int {
mod := size % 16
if mod > 0 {
return size + (16 - mod)
}
return size
}
// RemovePKCS7Padding 移除PKCS7填充
func RemovePKCS7Padding(data []byte) []byte {
length := len(data)
if length == 0 {
return data
}
paddingLen := int(data[length-1])
if paddingLen > length || paddingLen > 16 {
return data
}
return data[:length-paddingLen]
}
// AddPKCS7Padding 添加PKCS7填充
func AddPKCS7Padding(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padText := make([]byte, padding)
for i := range padText {
padText[i] = byte(padding)
}
return append(data, padText...)
}
+404
View File
@@ -0,0 +1,404 @@
package algos
import (
"fmt"
)
// ProtoFieldType 协议字段类型
type ProtoFieldType int
const (
ProtoFieldTypeVARINT ProtoFieldType = 0
ProtoFieldTypeINT64 ProtoFieldType = 1
ProtoFieldTypeSTRING ProtoFieldType = 2
ProtoFieldTypeGROUPSTART ProtoFieldType = 3
ProtoFieldTypeGROUPEND ProtoFieldType = 4
ProtoFieldTypeINT32 ProtoFieldType = 5
ProtoFieldTypeERROR1 ProtoFieldType = 6
ProtoFieldTypeERROR2 ProtoFieldType = 7
)
// ProtoField 协议字段
type ProtoField struct {
Idx int
Type ProtoFieldType
Val interface{}
}
// NewProtoField 创建新的协议字段
func NewProtoField(idx int, fieldType ProtoFieldType, val interface{}) *ProtoField {
return &ProtoField{
Idx: idx,
Type: fieldType,
Val: val,
}
}
// IsAsciiStr 检查是否为ASCII字符串
func (pf *ProtoField) IsAsciiStr() bool {
if data, ok := pf.Val.([]byte); ok {
for _, b := range data {
if b < 0x20 || b > 0x7E {
return false
}
}
return true
}
return false
}
// ProtoReader 协议读取器
type ProtoReader struct {
data []byte
pos int
}
// NewProtoReader 创建新的协议读取器
func NewProtoReader(data []byte) *ProtoReader {
return &ProtoReader{
data: data,
pos: 0,
}
}
// Seek 设置位置
func (pr *ProtoReader) Seek(pos int) {
pr.pos = pos
}
// IsRemain 检查是否还有剩余数据
func (pr *ProtoReader) IsRemain(length int) bool {
return pr.pos+length <= len(pr.data)
}
// Read0 读取一个字节
func (pr *ProtoReader) Read0() byte {
if !pr.IsRemain(1) {
panic("buffer overflow")
}
ret := pr.data[pr.pos]
pr.pos++
return ret & 0xFF
}
// Read 读取指定长度的字节
func (pr *ProtoReader) Read(length int) []byte {
if !pr.IsRemain(length) {
panic("buffer overflow")
}
ret := pr.data[pr.pos : pr.pos+length]
pr.pos += length
return ret
}
// ReadInt32 读取32位整数
func (pr *ProtoReader) ReadInt32() uint32 {
bytes := pr.Read(4)
return uint32(bytes[0]) | uint32(bytes[1])<<8 | uint32(bytes[2])<<16 | uint32(bytes[3])<<24
}
// ReadInt64 读取64位整数
func (pr *ProtoReader) ReadInt64() uint64 {
bytes := pr.Read(8)
return uint64(bytes[0]) | uint64(bytes[1])<<8 | uint64(bytes[2])<<16 | uint64(bytes[3])<<24 |
uint64(bytes[4])<<32 | uint64(bytes[5])<<40 | uint64(bytes[6])<<48 | uint64(bytes[7])<<56
}
// ReadVarint 读取可变长度整数
func (pr *ProtoReader) ReadVarint() uint64 {
vint := uint64(0)
n := 0
for {
b := pr.Read0()
vint |= uint64(b&0x7F) << (7 * n)
if b < 0x80 {
break
}
n++
}
return vint
}
// ReadString 读取字符串
func (pr *ProtoReader) ReadString() []byte {
length := pr.ReadVarint()
return pr.Read(int(length))
}
// ProtoWriter 协议写入器
type ProtoWriter struct {
data []byte
}
// NewProtoWriter 创建新的协议写入器
func NewProtoWriter() *ProtoWriter {
return &ProtoWriter{
data: make([]byte, 0),
}
}
// Write0 写入一个字节
func (pw *ProtoWriter) Write0(b byte) {
pw.data = append(pw.data, b&0xFF)
}
// Write 写入字节数组
func (pw *ProtoWriter) Write(bytes []byte) {
pw.data = append(pw.data, bytes...)
}
// WriteInt32 写入32位整数
func (pw *ProtoWriter) WriteInt32(val uint32) {
bs := []byte{
byte(val & 0xFF),
byte((val >> 8) & 0xFF),
byte((val >> 16) & 0xFF),
byte((val >> 24) & 0xFF),
}
pw.Write(bs)
}
// WriteInt64 写入64位整数
func (pw *ProtoWriter) WriteInt64(val uint64) {
bs := []byte{
byte(val & 0xFF),
byte((val >> 8) & 0xFF),
byte((val >> 16) & 0xFF),
byte((val >> 24) & 0xFF),
byte((val >> 32) & 0xFF),
byte((val >> 40) & 0xFF),
byte((val >> 48) & 0xFF),
byte((val >> 56) & 0xFF),
}
pw.Write(bs)
}
// WriteVarint 写入可变长度整数
func (pw *ProtoWriter) WriteVarint(vint uint64) {
vint = vint & 0xFFFFFFFF
for vint > 0x80 {
pw.Write0(byte((vint & 0x7F) | 0x80))
vint >>= 7
}
pw.Write0(byte(vint & 0x7F))
}
// WriteString 写入字符串
func (pw *ProtoWriter) WriteString(bytes []byte) {
pw.WriteVarint(uint64(len(bytes)))
pw.Write(bytes)
}
// ToBytes 转换为字节数组
func (pw *ProtoWriter) ToBytes() []byte {
return pw.data
}
// ProtoBuf 协议缓冲区
type ProtoBuf struct {
fields []*ProtoField
}
// NewProtoBuf 创建新的协议缓冲区
func NewProtoBuf(data interface{}) *ProtoBuf {
pb := &ProtoBuf{
fields: make([]*ProtoField, 0),
}
if data != nil {
switch v := data.(type) {
case []byte:
if len(v) > 0 {
pb.parseBuf(v)
}
case map[int]interface{}:
if len(v) > 0 {
pb.parseDict(v)
}
default:
panic(fmt.Sprintf("unsupported type(%T) to protobuf", data))
}
}
return pb
}
// parseBuf 解析字节数组
func (pb *ProtoBuf) parseBuf(bytes []byte) {
reader := NewProtoReader(bytes)
for reader.IsRemain(1) {
key := reader.ReadVarint()
fieldType := ProtoFieldType(key & 0x7)
fieldIdx := int(key >> 3)
if fieldIdx == 0 {
break
}
switch fieldType {
case ProtoFieldTypeINT32:
pb.Put(NewProtoField(fieldIdx, fieldType, reader.ReadInt32()))
case ProtoFieldTypeINT64:
pb.Put(NewProtoField(fieldIdx, fieldType, reader.ReadInt64()))
case ProtoFieldTypeVARINT:
pb.Put(NewProtoField(fieldIdx, fieldType, reader.ReadVarint()))
case ProtoFieldTypeSTRING:
pb.Put(NewProtoField(fieldIdx, fieldType, reader.ReadString()))
default:
panic(fmt.Sprintf("parse protobuf error, unexpected field type: %d", fieldType))
}
}
}
// ToBuf 转换为字节数组
func (pb *ProtoBuf) ToBuf() []byte {
writer := NewProtoWriter()
for _, field := range pb.fields {
key := uint64((field.Idx << 3) | int(field.Type&7))
writer.WriteVarint(key)
switch field.Type {
case ProtoFieldTypeINT32:
writer.WriteInt32(field.Val.(uint32))
case ProtoFieldTypeINT64:
writer.WriteInt64(field.Val.(uint64))
case ProtoFieldTypeVARINT:
writer.WriteVarint(field.Val.(uint64))
case ProtoFieldTypeSTRING:
writer.WriteString(field.Val.([]byte))
default:
panic(fmt.Sprintf("encode to protobuf error, unexpected field type: %d", field.Type))
}
}
return writer.ToBytes()
}
// Get 获取字段
func (pb *ProtoBuf) Get(idx int) *ProtoField {
for _, field := range pb.fields {
if field.Idx == idx {
return field
}
}
return nil
}
// GetList 获取字段列表
func (pb *ProtoBuf) GetList(idx int) []*ProtoField {
result := make([]*ProtoField, 0)
for _, field := range pb.fields {
if field.Idx == idx {
result = append(result, field)
}
}
return result
}
// GetInt 获取整数
func (pb *ProtoBuf) GetInt(idx int) uint64 {
pf := pb.Get(idx)
if pf == nil {
return 0
}
switch pf.Type {
case ProtoFieldTypeINT32:
return uint64(pf.Val.(uint32))
case ProtoFieldTypeINT64:
return pf.Val.(uint64)
case ProtoFieldTypeVARINT:
return pf.Val.(uint64)
default:
panic(fmt.Sprintf("getInt(%d) -> %d", idx, pf.Type))
}
}
// GetBytes 获取字节数组
func (pb *ProtoBuf) GetBytes(idx int) []byte {
pf := pb.Get(idx)
if pf == nil {
return nil
}
if pf.Type == ProtoFieldTypeSTRING {
return pf.Val.([]byte)
}
panic(fmt.Sprintf("getBytes(%d) -> %d", idx, pf.Type))
}
// GetUTF8 获取UTF8字符串
func (pb *ProtoBuf) GetUTF8(idx int) string {
bs := pb.GetBytes(idx)
if bs == nil {
return ""
}
return string(bs)
}
// GetProtoBuf 获取嵌套的ProtoBuf
func (pb *ProtoBuf) GetProtoBuf(idx int) *ProtoBuf {
bs := pb.GetBytes(idx)
if bs == nil {
return nil
}
return NewProtoBuf(bs)
}
// Put 添加字段
func (pb *ProtoBuf) Put(field *ProtoField) {
pb.fields = append(pb.fields, field)
}
// PutInt32 添加32位整数
func (pb *ProtoBuf) PutInt32(idx int, val uint32) {
pb.Put(NewProtoField(idx, ProtoFieldTypeINT32, val))
}
// PutInt64 添加64位整数
func (pb *ProtoBuf) PutInt64(idx int, val uint64) {
pb.Put(NewProtoField(idx, ProtoFieldTypeINT64, val))
}
// PutVarint 添加可变长度整数
func (pb *ProtoBuf) PutVarint(idx int, val uint64) {
pb.Put(NewProtoField(idx, ProtoFieldTypeVARINT, val))
}
// PutBytes 添加字节数组
func (pb *ProtoBuf) PutBytes(idx int, data []byte) {
pb.Put(NewProtoField(idx, ProtoFieldTypeSTRING, data))
}
// PutUTF8 添加UTF8字符串
func (pb *ProtoBuf) PutUTF8(idx int, data string) {
pb.Put(NewProtoField(idx, ProtoFieldTypeSTRING, []byte(data)))
}
// PutProtoBuf 添加嵌套的ProtoBuf
func (pb *ProtoBuf) PutProtoBuf(idx int, data *ProtoBuf) {
pb.Put(NewProtoField(idx, ProtoFieldTypeSTRING, data.ToBuf()))
}
// parseDict 解析字典
func (pb *ProtoBuf) parseDict(data map[int]interface{}) {
for k, v := range data {
switch val := v.(type) {
case int:
pb.PutVarint(k, uint64(val))
case uint64:
pb.PutVarint(k, val)
case int64:
pb.PutVarint(k, uint64(val))
case string:
pb.PutUTF8(k, val)
case []byte:
pb.PutBytes(k, val)
case map[int]interface{}:
pb.PutProtoBuf(k, NewProtoBuf(val))
default:
panic(fmt.Sprintf("unsupported type(%T) to protobuf", v))
}
}
}
+219
View File
@@ -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)
}
+85
View File
@@ -0,0 +1,85 @@
package algos
// getBit 获取指定位的值
func getBit(val uint64, pos int) uint64 {
if val&(1<<pos) != 0 {
return 1
}
return 0
}
// rotateLeft64 64位左循环移位
func rotateLeft64(v uint64, n int) uint64 {
r := (v << n) | (v >> (64 - n))
return r & 0xFFFFFFFFFFFFFFFF
}
// rotateRight64 64位右循环移位
func rotateRight64(v uint64, n int) uint64 {
r := (v << (64 - n)) | (v >> n)
return r & 0xFFFFFFFFFFFFFFFF
}
// keyExpansion 密钥扩展
func keyExpansion(key []uint64) []uint64 {
expandedKey := make([]uint64, 72)
copy(expandedKey, key[:4])
var tmp uint64
for i := 4; i < 72; i++ {
tmp = rotateRight64(expandedKey[i-1], 3)
tmp = tmp ^ expandedKey[i-3]
tmp = tmp ^ rotateRight64(tmp, 1)
expandedKey[i] = (^expandedKey[i-4]) ^ tmp ^ getBit(0x3DC94C3A046D678B, (i-4)%62) ^ 3
}
return expandedKey
}
// SimonEnc Simon加密
func SimonEnc(pt []uint64, k []uint64, c int) []uint64 {
key := make([]uint64, 72)
copy(key[:4], k[:4])
key = keyExpansion(key)
xi := pt[0]
xi1 := pt[1]
var tmp, f uint64
for i := 0; i < 72; i++ {
tmp = xi1
if c == 1 {
f = rotateLeft64(xi1, 1)
} else {
f = rotateLeft64(xi1, 1) & rotateLeft64(xi1, 8)
}
xi1 = xi ^ f ^ rotateLeft64(xi1, 2) ^ key[i]
xi = tmp
}
return []uint64{xi, xi1}
}
// SimonDec Simon解密
func SimonDec(ct []uint64, k []uint64, c int) []uint64 {
key := make([]uint64, 72)
copy(key[:4], k[:4])
key = keyExpansion(key)
xi := ct[0]
xi1 := ct[1]
var tmp, f uint64
for i := 71; i >= 0; i-- {
tmp = xi
if c == 1 {
f = rotateLeft64(xi, 1)
} else {
f = rotateLeft64(xi, 1) & rotateLeft64(xi, 8)
}
xi = xi1 ^ f ^ rotateLeft64(xi, 2) ^ key[i]
xi1 = tmp
}
return []uint64{xi, xi1}
}
+154
View File
@@ -0,0 +1,154 @@
package algos
// SM3 SM3哈希算法实现
type SM3 struct {
IV []uint32
TJ []uint32
}
// NewSM3 创建SM3实例
func NewSM3() *SM3 {
return &SM3{
IV: []uint32{1937774191, 1226093241, 388252375, 3666478592, 2842636476, 372324522, 3817729613, 2969243214},
TJ: []uint32{
2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
},
}
}
// rotateLeft 循环左移
func (sm3 *SM3) rotateLeft(a uint32, k int) uint32 {
k = k % 32
return ((a << uint(k)) & 0xFFFFFFFF) | ((a & 0xFFFFFFFF) >> uint(32-k))
}
// FFJ FF函数
func (sm3 *SM3) FFJ(X, Y, Z uint32, j int) uint32 {
if j >= 0 && j < 16 {
return X ^ Y ^ Z
} else if j >= 16 && j < 64 {
return (X & Y) | (X & Z) | (Y & Z)
}
return 0
}
// GGJ GG函数
func (sm3 *SM3) GGJ(X, Y, Z uint32, j int) uint32 {
if j >= 0 && j < 16 {
return X ^ Y ^ Z
} else if j >= 16 && j < 64 {
return (X & Y) | ((^X) & Z)
}
return 0
}
// P0 压缩函数P0
func (sm3 *SM3) P0(X uint32) uint32 {
return X ^ sm3.rotateLeft(X, 9) ^ sm3.rotateLeft(X, 17)
}
// P1 压缩函数P1
func (sm3 *SM3) P1(X uint32) uint32 {
return X ^ sm3.rotateLeft(X, 15) ^ sm3.rotateLeft(X, 23)
}
// CF 压缩函数
func (sm3 *SM3) CF(Vi []uint32, Bi []byte) []uint32 {
W := make([]uint32, 68)
for i := 0; i < 16; i++ {
weight := uint32(0x1000000)
data := uint32(0)
for k := i * 4; k < (i+1)*4; k++ {
data = data + uint32(Bi[k])*weight
weight = weight / 0x100
}
W[i] = data
}
for j := 16; j < 68; j++ {
W[j] = sm3.P1(W[j-16]^W[j-9]^sm3.rotateLeft(W[j-3], 15)) ^ sm3.rotateLeft(W[j-13], 7) ^ W[j-6]
}
W1 := make([]uint32, 64)
for j := 0; j < 64; j++ {
W1[j] = W[j] ^ W[j+4]
}
A, B, C, D, E, F, G, H := Vi[0], Vi[1], Vi[2], Vi[3], Vi[4], Vi[5], Vi[6], Vi[7]
for j := 0; j < 64; j++ {
SS1 := sm3.rotateLeft((sm3.rotateLeft(A, 12)+E+sm3.rotateLeft(sm3.TJ[j], j%32))&0xFFFFFFFF, 7)
SS2 := SS1 ^ sm3.rotateLeft(A, 12)
TT1 := (sm3.FFJ(A, B, C, j) + D + SS2 + W1[j]) & 0xFFFFFFFF
TT2 := (sm3.GGJ(E, F, G, j) + H + SS1 + W[j]) & 0xFFFFFFFF
D = C
C = sm3.rotateLeft(B, 9)
B = A
A = TT1
H = G
G = sm3.rotateLeft(F, 19)
F = E
E = sm3.P0(TT2)
}
V := make([]uint32, 8)
V[0] = A ^ Vi[0]
V[1] = B ^ Vi[1]
V[2] = C ^ Vi[2]
V[3] = D ^ Vi[3]
V[4] = E ^ Vi[4]
V[5] = F ^ Vi[5]
V[6] = G ^ Vi[6]
V[7] = H ^ Vi[7]
return V
}
// Hash 计算SM3哈希
func (sm3 *SM3) Hash(msg []byte) []byte {
msgLen := len(msg)
reserve1 := msgLen % 64
paddingLen := 0
if reserve1 > 55 {
paddingLen = 64 - reserve1 + 64
} else {
paddingLen = 64 - reserve1
}
msgPadding := make([]byte, msgLen+paddingLen)
copy(msgPadding, msg)
msgPadding[msgLen] = 0x80
lengthBits := uint64(msgLen) * 8
for i := 0; i < 8; i++ {
msgPadding[len(msgPadding)-1-i] = byte(lengthBits >> uint(8*i))
}
groupCount := len(msgPadding) / 64
V := make([]uint32, len(sm3.IV))
copy(V, sm3.IV)
for i := 0; i < groupCount; i++ {
B := msgPadding[i*64 : (i+1)*64]
V = sm3.CF(V, B)
}
result := make([]byte, 32)
for i := 0; i < 8; i++ {
result[i*4] = byte((V[i] >> 24) & 0xFF)
result[i*4+1] = byte((V[i] >> 16) & 0xFF)
result[i*4+2] = byte((V[i] >> 8) & 0xFF)
result[i*4+3] = byte(V[i] & 0xFF)
}
return result
}
+159
View File
@@ -0,0 +1,159 @@
package algos
import (
"fmt"
"strings"
"sync"
"time"
)
// AlgorithmInterface 算法接口
type AlgorithmInterface interface {
GetAlgorithmName() string
GenerateHeaders(url string, headers map[string]string) (map[string]string, error)
}
// AlgorithmSwitcher 算法切换器
type AlgorithmSwitcher struct {
mu sync.RWMutex
currentAlgorithm string
algorithms map[string]AlgorithmInterface
}
// NewAlgorithmSwitcher 创建算法切换器
func NewAlgorithmSwitcher() *AlgorithmSwitcher {
switcher := &AlgorithmSwitcher{
algorithms: make(map[string]AlgorithmInterface),
}
// 注册所有算法
switcher.algorithms["gorgon"] = &GorgonAlgorithmAdapter{}
switcher.algorithms["8404"] = &Algo8404Adapter{}
// 设置默认算法为gorgon
switcher.currentAlgorithm = "gorgon"
return switcher
}
// SwitchAlgorithm 切换算法
func (s *AlgorithmSwitcher) SwitchAlgorithm(algorithmType string) error {
s.mu.Lock()
defer s.mu.Unlock()
if _, exists := s.algorithms[algorithmType]; !exists {
return fmt.Errorf("不支持的算法类型: %s", algorithmType)
}
s.currentAlgorithm = algorithmType
return nil
}
// GetCurrentAlgorithm 获取当前算法名称
func (s *AlgorithmSwitcher) GetCurrentAlgorithm() string {
s.mu.RLock()
defer s.mu.RUnlock()
return s.currentAlgorithm
}
// GetAvailableAlgorithms 获取可用算法列表
func (s *AlgorithmSwitcher) GetAvailableAlgorithms() []string {
s.mu.RLock()
defer s.mu.RUnlock()
algorithms := make([]string, 0, len(s.algorithms))
for name := range s.algorithms {
algorithms = append(algorithms, name)
}
return algorithms
}
// GetCurrentAlgorithmInstance 获取当前算法实例
func (s *AlgorithmSwitcher) GetCurrentAlgorithmInstance() AlgorithmInterface {
s.mu.RLock()
defer s.mu.RUnlock()
return s.algorithms[s.currentAlgorithm]
}
// GetAlgorithmInstance 获取指定算法实例
func (s *AlgorithmSwitcher) GetAlgorithmInstance(algorithmType string) (AlgorithmInterface, error) {
s.mu.RLock()
defer s.mu.RUnlock()
algorithm, exists := s.algorithms[algorithmType]
if !exists {
return nil, fmt.Errorf("不支持的算法类型: %s", algorithmType)
}
return algorithm, nil
}
// GorgonAlgorithmAdapter Gorgon算法适配器(兼容旧版)
type GorgonAlgorithmAdapter struct{}
func (g *GorgonAlgorithmAdapter) GetAlgorithmName() string {
return "Gorgon算法"
}
func (g *GorgonAlgorithmAdapter) GenerateHeaders(url string, headers map[string]string) (map[string]string, error) {
// 使用Gorgon算法
parts := strings.Split(url, "?")
if len(parts) < 2 {
return headers, fmt.Errorf("URL格式错误")
}
xSSStub := headers["x-ss-stub"]
cookie := headers["Cookie"]
if cookie == "" {
cookie = headers["cookie"]
}
gorgon := NewGorgon(parts[1], time.Now().Unix(), xSSStub, cookie)
result := gorgon.GetValue()
finalHeaders := make(map[string]string)
for k, v := range headers {
finalHeaders[k] = v
}
for k, v := range result {
finalHeaders[k] = v
}
return finalHeaders, nil
}
// Algo8404Adapter 8404算法适配器
type Algo8404Adapter struct{}
func (a *Algo8404Adapter) GetAlgorithmName() string {
return "8404算法"
}
func (a *Algo8404Adapter) GenerateHeaders(url string, headers map[string]string) (map[string]string, error) {
// 使用8404算法
parts := strings.Split(url, "?")
if len(parts) < 2 {
return headers, fmt.Errorf("URL格式错误")
}
xSSStub := headers["x-ss-stub"]
algo := NewAlgo8404(parts[1], time.Now().Unix(), xSSStub)
result := algo.GetValue()
finalHeaders := make(map[string]string)
for k, v := range headers {
finalHeaders[k] = v
}
for k, v := range result {
finalHeaders[k] = v
}
return finalHeaders, nil
}
// GlobalAlgorithmSwitcher 全局算法切换器实例
var GlobalAlgorithmSwitcher = NewAlgorithmSwitcher()