Files
go-roots/events/id.go
T

87 lines
2.1 KiB
Go

package events
import (
"crypto/sha256"
"encoding/hex"
"strconv"
)
// GetID computes and returns the event ID as a lowercase, hex-encoded SHA-256 hash
// of the serialized event.
func GetID(e Event) string {
hash := GetIDBytes(e)
return hex.EncodeToString(hash[:])
}
// GetIDBytes computes and returns the event ID as a raw SHA256 digest
func GetIDBytes(e Event) [32]byte {
return sha256.Sum256(Serialize(e))
}
// Serialize returns the canonical JSON array representation of the event.
// used for ID computation: [0, pubkey, created_at, kind, tags, content].
func Serialize(e Event) []byte {
buf := make([]byte, 0, 100+len(e.Content)+len(e.Tags)*80)
return appendSerialized(buf, e)
}
func appendSerialized(dst []byte, e Event) []byte {
dst = append(dst, "[0,\""...)
dst = append(dst, e.PubKey...)
dst = append(dst, "\","...)
dst = strconv.AppendInt(dst, int64(e.CreatedAt), 10)
dst = append(dst, ',')
dst = strconv.AppendInt(dst, int64(e.Kind), 10)
dst = append(dst, ",["...)
for i, tag := range e.Tags {
if i > 0 {
dst = append(dst, ',')
}
dst = append(dst, '[')
for j, s := range tag {
if j > 0 {
dst = append(dst, ',')
}
dst = appendEscapedString(dst, s)
}
dst = append(dst, ']')
}
dst = append(dst, "],"...)
dst = appendEscapedString(dst, e.Content)
return append(dst, ']')
}
func appendEscapedString(dst []byte, s string) []byte {
dst = append(dst, '"')
for i := 0; i < len(s); i++ {
c := s[i]
switch {
case c == '"':
dst = append(dst, '\\', '"')
case c == '\\':
dst = append(dst, '\\', '\\')
case c >= 0x20:
dst = append(dst, c)
case c == 0x08:
dst = append(dst, '\\', 'b')
case c == 0x09:
dst = append(dst, '\\', 't')
case c == 0x0a:
dst = append(dst, '\\', 'n')
case c == 0x0c:
dst = append(dst, '\\', 'f')
case c == 0x0d:
dst = append(dst, '\\', 'r')
case c < 0x09:
dst = append(dst, '\\', 'u', '0', '0', '0', '0'+c)
case c < 0x10:
dst = append(dst, '\\', 'u', '0', '0', '0', 0x57+c)
case c < 0x1a:
dst = append(dst, '\\', 'u', '0', '0', '1', 0x20+c)
case c < 0x20:
dst = append(dst, '\\', 'u', '0', '0', '1', 0x47+c)
}
}
return append(dst, '"')
}