a329d4906b
- 方案文档: AVCC 体系建设、IPTV TCS 需求(0-req)/PRD(1-prd)/任务(2-task)/二三四期任务 - tcs-iptv: Go 后端(哈希SDK/MA码生成/可信数据空间mock/业务编排/HTTP API+HMAC鉴权) - web-console: React+AntD 监管大屏(角色工作台/全流程演示/监管片库) - 一剧一码+集级哈希, 集级下架/恢复, 全栈测试通过
71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
package macode
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
// Parsed 是解析后的 MA 码各段。
|
|
type Parsed struct {
|
|
Root string
|
|
CountryCode string
|
|
IndustryNode string
|
|
OrgNode string
|
|
Category string
|
|
Year int
|
|
Sequence uint64
|
|
}
|
|
|
|
// maCodePattern 匹配六段式 MA 码:
|
|
// MA.156.{industry}.{org}/{category}/{yyyy}{sequence}
|
|
var maCodePattern = regexp.MustCompile(
|
|
`^(MA)\.(\d{3})\.([0-9A-Za-z]+)\.([0-9A-Za-z]+)/([A-Z]{2})/(\d{4})(\d+)$`)
|
|
|
|
// Parse 将 MA 码字符串解析为结构化字段;格式非法返回错误(需求4 校验基础)。
|
|
func Parse(code string) (Parsed, error) {
|
|
m := maCodePattern.FindStringSubmatch(code)
|
|
if m == nil {
|
|
return Parsed{}, fmt.Errorf("macode: invalid format: %s", code)
|
|
}
|
|
year, _ := strconv.Atoi(m[6])
|
|
seq, err := strconv.ParseUint(m[7], 10, 64)
|
|
if err != nil {
|
|
return Parsed{}, fmt.Errorf("macode: invalid sequence: %w", err)
|
|
}
|
|
return Parsed{
|
|
Root: m[1],
|
|
CountryCode: m[2],
|
|
IndustryNode: m[3],
|
|
OrgNode: m[4],
|
|
Category: m[5],
|
|
Year: year,
|
|
Sequence: seq,
|
|
}, nil
|
|
}
|
|
|
|
// IsValid 仅校验格式合法性。
|
|
func IsValid(code string) bool {
|
|
return maCodePattern.MatchString(code)
|
|
}
|
|
|
|
// EpisodeSubID 生成集级子标识:{maCode}#E{NN}。
|
|
// 整剧用 MA 码,单集用子标识,便于按集验真/追更/下架。
|
|
func EpisodeSubID(maCode string, episode int) string {
|
|
return fmt.Sprintf("%s#E%02d", maCode, episode)
|
|
}
|
|
|
|
// episodeSubPattern 匹配集级子标识后缀。
|
|
var episodeSubPattern = regexp.MustCompile(`^(.+)#E(\d+)$`)
|
|
|
|
// ParseEpisodeSubID 拆解集级子标识,返回主 MA 码与集号。
|
|
// 若无 #E 后缀,episode 返回 0(表示整剧)。
|
|
func ParseEpisodeSubID(subID string) (maCode string, episode int) {
|
|
m := episodeSubPattern.FindStringSubmatch(subID)
|
|
if m == nil {
|
|
return subID, 0
|
|
}
|
|
ep, _ := strconv.Atoi(m[2])
|
|
return m[1], ep
|
|
}
|