Files
fanqie-go/internal/algos/ladon.go
T
chenxin 6981148727 🔧 chore: 初始化番茄小说 API 项目结构
新增项目基础框架,包含核心 API 实现、算法模块、HTTP 处理器等完整功能模块
2026-08-28 15:22:22 +08:00

122 lines
3.0 KiB
Go

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)
}