// Package checksum defines the content hash used to spot duplicate photos and // the backfill that fills it in for photos uploaded before it existed. // // The hash is sha256 over the untouched original bytes, hex encoded, stored in // photos_photos.checksum. Duplicate scope is one gallery — the unique index is // on (gallery_id, checksum) — so the same image may still live in several // galleries, each with its own row and its own stored object. package checksum import ( "crypto/sha256" "encoding/hex" "hash" "io" ) // New returns a fresh hasher. Upload hashes as it spools the body, so it needs // the writer rather than a finished reader. func New() hash.Hash { return sha256.New() } // Format renders a hasher's digest the way it is stored. func Format(h hash.Hash) string { return hex.EncodeToString(h.Sum(nil)) } // Sum reads r to EOF and returns its digest. func Sum(r io.Reader) (string, error) { h := New() if _, err := io.Copy(h, r); err != nil { return "", err } return Format(h), nil }