package protocol import ( "crypto/sha256" "encoding/binary" "encoding/hex" ) // RequestFingerprint 计算第 7.3 节发送请求指纹(十六进制小写 SHA-256)。 // 字段:to.kind、to.id、body.enc、content_type、解码后正文、meta(键排序)、 // send_at_ms、delay_ms、offline.keep、offline.ttl_seconds、receipt。 // 不含 talk_password 与 rid。meta 键顺序不影响结果。 // receipt / offline 使用文档默认值后的有效值;缺省的 send_at_ms、delay_ms 不写入对应槽位。 func RequestFingerprint(s *Send) (string, error) { raw, err := DecodeBody(s.Body) if err != nil { return "", err } metaJSON, err := MetaCanonicalJSON(s.Meta) if err != nil { return "", badRequest("invalid meta") } h := sha256.New() writeStr(h, s.To.Kind) writeStr(h, s.To.ID) writeStr(h, s.Body.Enc) writeStr(h, EffectiveContentType(s.Body)) writeBytes(h, raw) writeBytes(h, metaJSON) writeOptInt64(h, s.SendAtMs) writeOptInt64(h, s.DelayMs) keep := EffectiveOfflineKeep(s) writeBool(h, keep) ttl := EffectiveOfflineTTL(s) writeInt64(h, ttl) writeBool(h, EffectiveReceipt(s)) sum := h.Sum(nil) return hex.EncodeToString(sum), nil } type hashWriter interface { Write(p []byte) (int, error) } func writeStr(h hashWriter, s string) { writeBytes(h, []byte(s)) } func writeBytes(h hashWriter, b []byte) { var lenBuf [8]byte binary.BigEndian.PutUint64(lenBuf[:], uint64(len(b))) _, _ = h.Write(lenBuf[:]) _, _ = h.Write(b) } func writeBool(h hashWriter, v bool) { if v { _, _ = h.Write([]byte{1}) } else { _, _ = h.Write([]byte{0}) } } func writeInt64(h hashWriter, v int64) { var buf [8]byte binary.BigEndian.PutUint64(buf[:], uint64(v)) _, _ = h.Write(buf[:]) } func writeOptInt64(h hashWriter, v *int64) { if v == nil { _, _ = h.Write([]byte{0}) return } _, _ = h.Write([]byte{1}) writeInt64(h, *v) }