Use the crypto/sha256 package from the standard library to compute hashes, either by creating a hash object and writing data to it or by calling the convenient Sum256 function for simple byte slices. Both approaches produce a 32-byte digest that you typically convert to a hexadecimal string for display or storage.
Here is the most common pattern using Sum256 for a quick one-liner, followed by the streaming approach for large data:
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
)
func main() {
// Method 1: Quick hash for small byte slices
data := []byte("Hello, Go!")
hash := sha256.Sum256(data)
fmt.Printf("Quick hash: %s\n", hex.EncodeToString(hash[:]))
// Method 2: Streaming hash for large files or readers
reader := &io.LimitedReader{R: &io.LimitedReader{R: &io.LimitedReader{R: nil, N: 0}, N: 0}, N: 0} // Placeholder for actual reader
// In practice, you would pass an actual io.Reader here, e.g., a file or network stream
// hashStream := sha256.New()
// io.Copy(hashStream, reader)
// fmt.Printf("Stream hash: %s\n", hex.EncodeToString(hashStream.Sum(nil)))
}
For a practical file hashing example, which is the most common use case, use sha256.New() and io.Copy:
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
)
func hashFile(path string) (string, error) {
file, err := os.Open(path)
if err != nil {
return "", err
}
defer file.Close()
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
return "", err
}
return hex.EncodeToString(hash.Sum(nil)), nil
}
func main() {
h, err := hashFile("data.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("File SHA-256:", h)
}
Remember that Sum256 returns a fixed-size array ([32]byte), so you must slice it (hash[:]) before converting to a string. The streaming method (New(), Write/Copy, Sum(nil)) is preferred for large files or network streams as it avoids loading the entire payload into memory at once. Always use encoding/hex to convert the binary digest into a human-readable format.