Compare commits

..
2 Commits
Author SHA1 Message Date
chenxin 292b8c656f 🧪 test(algos): 新增签名算法 golden 测试
固定输入与时间戳断言 Gorgon/8404/Ladon 输出及 Argus 哈希层。
Go 1.25 起 rand.Seed 默认 no-op,用 //go:debug randseednop=0 钉住随机序列;
Argus 因 protobuf 按 map 迭代序编码无法全量 golden,仅测其确定性哈希。
2026-10-08 13:50:46 +08:00
chenxin 6e1a21314a 📝 docs(readme): 修正 Go 版本要求为 1.25 2026-10-08 13:50:46 +08:00
2 changed files with 81 additions and 2 deletions

No files matched your search

+2 -2
View File
@@ -111,7 +111,7 @@ fanqie-go/
### 环境要求
- Go 1.24+
- Go 1.25+
- SQLite3
### 安装运行
@@ -397,7 +397,7 @@ cp .env.example .env
## 技术栈
- **Go 1.24** - 编程语言
- **Go 1.25** - 编程语言
- **net/http** - 标准库 HTTP 服务(超时保护 + 优雅退出)
- **SQLite3 / PostgreSQL / Redis** - 缓存与存储
- **Viper** - 配置管理
+79
View File
@@ -0,0 +1,79 @@
//go:debug randseednop=0
package algos
import (
"encoding/hex"
"math/rand"
"testing"
)
// 固定输入 + 固定时间戳的 golden 测试:签名算法被改坏时在此最先失败。
// 基准值取自当前实现;有意修改算法后用相同输入重新生成并更新期望值。
// 8404 内嵌随机数且走全局 math/rand,Go 1.25 起 rand.Seed 默认是 no-op,
// 故用 //go:debug randseednop=0 恢复其钉死随机序列的旧语义。
// x-argus 的 protobuf 编码按 map 迭代顺序输出(protobuf.go:385),天然
// 不确定,无法全量 golden,只测其内部的确定性哈希层。
const (
goldenParams = "aid=1967&app_name=fanqie_novel&device_id=1234567890123456&version_name=5.9.5"
goldenStub = "d41d8cd98f00b204e9800998ecf8427e"
goldenCookie = "install_id=728944090949322; device_id=1234567890123456"
goldenSecDev = "1234567890123456"
goldenAID = 1967
goldenLcID = 1611921764
)
// var:Sign2 需要 *int64,不能对常量取址
var goldenTS = int64(1700000000)
func goldenArgs() (string, string, string, string, int, int, string, int, int, *int64) {
return goldenParams, goldenStub, goldenSecDev, goldenCookie,
goldenAID, goldenLcID, "v04.06.01-ml-android", 135004672, 0, &goldenTS
}
func assertGolden(t *testing.T, name string, got map[string]string, want map[string]string) {
t.Helper()
for k, v := range want {
if got[k] != v {
t.Errorf("%s %s = %q, want %q", name, k, got[k], v)
}
}
}
func TestGorgonSign2Golden(t *testing.T) {
GlobalAlgorithmSwitcher.SwitchAlgorithm("gorgon")
assertGolden(t, "gorgon", Sign2(goldenArgs()), map[string]string{
"x-gorgon": "0404b0d30000bbd9e75fe1edb046d324b7853694a6177ca72d0a",
"x-khronos": "1700000000",
"x-ss-req-ticket": "1700000000000",
})
}
func TestAlgo8404Sign2Golden(t *testing.T) {
rand.Seed(1)
GlobalAlgorithmSwitcher.SwitchAlgorithm("8404")
defer GlobalAlgorithmSwitcher.SwitchAlgorithm("gorgon")
assertGolden(t, "8404", Sign2(goldenArgs()), map[string]string{
"X-Gorgon": "8404210f00008eec413318e9f810571e96fca6fb4a0f497e78e5",
"X-Khronos": "1700000000",
"X-SS-REQ-Ticket": "1700000000000",
})
}
func TestLadonGolden(t *testing.T) {
// 固定 randomBytes,绕开 crypto/rand
got := LadonEncrypt(goldenTS, goldenLcID, goldenAID, []byte{0xde, 0xad, 0xbe, 0xef})
if want := "3q2+7/6PK4T/ZqM1zu2AIWFdXW2D9gdHrXRfOb02lxi6GnYm"; got != want {
t.Errorf("ladon = %q, want %q", got, want)
}
}
func TestArgusHashGolden(t *testing.T) {
if got := hex.EncodeToString(GetBodyHash(goldenStub)); got != "9c840df1aec0" {
t.Errorf("bodyHash = %s, want 9c840df1aec0", got)
}
if got := hex.EncodeToString(GetQueryHash(goldenParams)); got != "58bc068af10b" {
t.Errorf("queryHash = %s, want 58bc068af10b", got)
}
}