代码提交

This commit is contained in:
2026-11-05 12:11:56 +08:00
parent 3d9bdb6f6e
commit 3fd3e82a01
18 changed files with 431 additions and 58 deletions
+49 -1
View File
@@ -17,6 +17,7 @@ import (
"stat/statg"
"time"
"github.com/google/uuid"
"github.com/xxjwxc/public/myglobal/snowflake"
)
@@ -51,7 +52,54 @@ func GenerateConfigFile(origin, target, configFile, DC, PC string) ([]byte, stri
if err != nil {
output, _ = os.ReadFile("conf/" + configFile)
}
return output, configFile
return uniqueProfileIdentity(output, configFile), configFile
}
// profileIDNamespace 标识符派生的固定命名空间,保证同一模板每次生成的值一致
var profileIDNamespace = uuid.NewSHA1(uuid.NameSpaceURL, []byte("stat_center/mobileconfig"))
var (
rePayloadIdent = regexp.MustCompile(`(<key>PayloadIdentifier</key>[ \t]*\r?\n[ \t]*<string>)([^<]*)(</string>)`)
rePayloadUUID = regexp.MustCompile(`(<key>PayloadUUID</key>[ \t]*\r?\n[ \t]*<string>)([^<]*)(</string>)`)
reUUIDValue = regexp.MustCompile(`[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}`)
)
// uniqueProfileIdentity 把 mobileconfig 里的 PayloadIdentifier/PayloadUUID 改写成按 configFile 派生的值。
// conf 下各 app 的模板是互相复制出来的,标识符完全相同,而 iOS 按顶层 PayloadIdentifier 判重:
// 相同即替换已安装的描述文件,用户装了第二个 app 第一个就没了。
// 按 configFile 派生可保证各 app 互不覆盖;同一 app 多次下载得到相同标识符,
// 重复安装只覆盖自己,不会在桌面堆出一排图标。
func uniqueProfileIdentity(data []byte, configFile string) []byte {
if len(data) == 0 {
return data
}
derive := func(i int) string {
return uuid.NewSHA1(profileIDNamespace, []byte(fmt.Sprintf("%s#%d", configFile, i))).String()
}
n := 0
data = rePayloadUUID.ReplaceAllFunc(data, func(m []byte) []byte {
g := rePayloadUUID.FindSubmatch(m)
v := derive(n)
n++
return []byte(string(g[1]) + v + string(g[3]))
})
// 第 i 个 PayloadIdentifier 与第 i 个 PayloadUUID 共用派生值,保留原前缀(luli. / com.apple.webClip.managed.)
i := 0
data = rePayloadIdent.ReplaceAllFunc(data, func(m []byte) []byte {
g := rePayloadIdent.FindSubmatch(m)
v := derive(i)
i++
val := g[2]
if reUUIDValue.Match(val) {
val = reUUIDValue.ReplaceAll(val, []byte(v))
} else {
val = []byte(string(val) + "." + v)
}
return []byte(string(g[1]) + string(val) + string(g[3]))
})
return data
}
func GetAppConfig(appId int32) (origin, target, config string) {
+90
View File
@@ -0,0 +1,90 @@
package versionSer
import (
"os"
"path/filepath"
"regexp"
"testing"
)
var reAllIdent = regexp.MustCompile(`<key>Payload(?:Identifier|UUID)</key>[ \t]*\r?\n[ \t]*<string>([^<]*)</string>`)
func collectIdentity(t *testing.T, data []byte) []string {
t.Helper()
var out []string
for _, m := range reAllIdent.FindAllSubmatch(data, -1) {
out = append(out, string(m[1]))
}
return out
}
// TestUniqueProfileIdentityMatchesTemplates 确认 uniqueProfileIdentity 的派生结果与 conf 下
// 已改好的模板完全一致:两边用同一套规则,部署后不会再变一次标识符。
func TestUniqueProfileIdentityMatchesTemplates(t *testing.T) {
files, err := filepath.Glob("../../conf/*.mobileconfig")
if err != nil || len(files) == 0 {
t.Fatalf("找不到 mobileconfig 模板: %v", err)
}
seen := make(map[string]string)
for _, path := range files {
name := filepath.Base(path)
raw, err := os.ReadFile(path)
if err != nil {
t.Fatalf("%s 读取失败: %v", name, err)
}
want := collectIdentity(t, raw)
if len(want) == 0 {
t.Fatalf("%s 没有解析到任何标识符", name)
}
got := collectIdentity(t, uniqueProfileIdentity(raw, name))
if len(got) != len(want) {
t.Fatalf("%s 标识符数量不一致: got %d want %d", name, len(got), len(want))
}
for i := range want {
if got[i] != want[i] {
t.Errorf("%s 第 %d 个标识符不一致:\n got %s\n want %s", name, i, got[i], want[i])
}
}
// 跨文件判重:顶层 PayloadIdentifier 相同会让 iOS 覆盖安装
for _, v := range got {
if prev, ok := seen[v]; ok {
t.Errorf("标识符 %s 同时出现在 %s 和 %s,iOS 上会互相覆盖", v, prev, name)
}
seen[v] = name
}
}
}
// TestUniqueProfileIdentityIsStable 同一模板多次生成必须得到相同标识符,
// 否则用户每次下载都会在桌面多出一个图标。
func TestUniqueProfileIdentityIsStable(t *testing.T) {
raw, err := os.ReadFile("../../conf/hgmj.mobileconfig")
if err != nil {
t.Skipf("模板不存在: %v", err)
}
a := collectIdentity(t, uniqueProfileIdentity(raw, "hgmj.mobileconfig"))
b := collectIdentity(t, uniqueProfileIdentity(raw, "hgmj.mobileconfig"))
for i := range a {
if a[i] != b[i] {
t.Fatalf("第 %d 个标识符不稳定: %s != %s", i, a[i], b[i])
}
}
}
// TestUniqueProfileIdentityDiffersByConfigFile 不同 configFile 必须派生出不同标识符。
func TestUniqueProfileIdentityDiffersByConfigFile(t *testing.T) {
raw, err := os.ReadFile("../../conf/hgmj.mobileconfig")
if err != nil {
t.Skipf("模板不存在: %v", err)
}
a := collectIdentity(t, uniqueProfileIdentity(raw, "hgmj.mobileconfig"))
b := collectIdentity(t, uniqueProfileIdentity(raw, "newapp.mobileconfig"))
for i := range a {
if a[i] == b[i] {
t.Fatalf("不同 configFile 派生出相同标识符: %s", a[i])
}
}
}