a329d4906b
- 方案文档: AVCC 体系建设、IPTV TCS 需求(0-req)/PRD(1-prd)/任务(2-task)/二三四期任务 - tcs-iptv: Go 后端(哈希SDK/MA码生成/可信数据空间mock/业务编排/HTTP API+HMAC鉴权) - web-console: React+AntD 监管大屏(角色工作台/全流程演示/监管片库) - 一剧一码+集级哈希, 集级下架/恢复, 全栈测试通过
69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
// Package hash 实现 TCS-IPTV 的内容哈希核心:
|
|
// 文件 SHA-256、分段 Merkle Tree、感知哈希。
|
|
// 对应需求:需求1(母版哈希生成)。
|
|
package hash
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
// DefaultSegmentSize 是分段哈希的默认分段大小(10 MiB)。
|
|
const DefaultSegmentSize = 10 * 1024 * 1024
|
|
|
|
// ErrEmptyInput 表示输入为空。
|
|
var ErrEmptyInput = errors.New("hash: empty input")
|
|
|
|
// SHA256Hex 计算字节切片的 SHA-256,返回十六进制字符串。
|
|
func SHA256Hex(data []byte) string {
|
|
sum := sha256.Sum256(data)
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
// FileSHA256 流式计算文件的整体 SHA-256,避免一次性载入大文件。
|
|
func FileSHA256(path string) (string, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer f.Close()
|
|
|
|
h := sha256.New()
|
|
if _, err := io.Copy(h, f); err != nil {
|
|
return "", err
|
|
}
|
|
return hex.EncodeToString(h.Sum(nil)), nil
|
|
}
|
|
|
|
// SegmentHashes 按 segmentSize 分段计算文件各段的 SHA-256。
|
|
// 用于构建 Merkle Tree 的叶子节点。
|
|
func SegmentHashes(path string, segmentSize int) ([]string, error) {
|
|
if segmentSize <= 0 {
|
|
segmentSize = DefaultSegmentSize
|
|
}
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
var segments []string
|
|
buf := make([]byte, segmentSize)
|
|
for {
|
|
n, err := io.ReadFull(f, buf)
|
|
if n > 0 {
|
|
segments = append(segments, SHA256Hex(buf[:n]))
|
|
}
|
|
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return segments, nil
|
|
}
|