The hash package provides interfaces for hash functions used throughout the Go standard library.
Overview
This package defines common interfaces that all hash functions implement. The actual hash implementations are in separate packages like:
crypto/md5
crypto/sha1
crypto/sha256
crypto/sha512
hash/crc32
hash/crc64
Hash Interface
The common interface implemented by all hash functions.
type Hash interface {
io.Writer
Sum(b []byte) []byte
Reset()
Size() int
BlockSize() int
}
Methods
Write()
Adds more data to the running hash. Inherited from io.Writer.
Write(p []byte) (n int, err error)
This method never returns an error.
Sum()
Appends the current hash to the provided byte slice and returns the result.
Does not change the underlying hash state.
Reset()
Resets the hash to its initial state.
Size()
Returns the number of bytes Sum will return.
BlockSize()
Returns the hash’s underlying block size.
The Write method operates more efficiently if all writes are a multiple of the block size.
Example Usage
import (
"crypto/sha256"
"fmt"
"hash"
)
func computeHash(data []byte, h hash.Hash) []byte {
h.Reset()
h.Write(data)
return h.Sum(nil)
}
func main() {
data := []byte("hello world")
h := sha256.New()
checksum := computeHash(data, h)
fmt.Printf("%x\n", checksum)
// Output: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
}
Hash32 Interface
The common interface for 32-bit hash functions.
type Hash32 interface {
Hash
Sum32() uint32
}
Sum32()
Returns the current hash as a uint32.
Example:
import (
"hash/crc32"
"fmt"
)
h := crc32.NewIEEE()
h.Write([]byte("hello world"))
checksum := h.Sum32()
fmt.Printf("CRC32: 0x%08x\n", checksum)
Hash64 Interface
The common interface for 64-bit hash functions.
type Hash64 interface {
Hash
Sum64() uint64
}
Sum64()
Returns the current hash as a uint64.
Example:
import (
"hash/crc64"
"fmt"
)
table := crc64.MakeTable(crc64.ISO)
h := crc64.New(table)
h.Write([]byte("hello world"))
checksum := h.Sum64()
fmt.Printf("CRC64: 0x%016x\n", checksum)
Cloner Interface
Interface for hash functions whose state can be cloned.
type Cloner interface {
Hash
Clone() (Cloner, error)
}
All Hash implementations in the standard library implement this interface unless GOFIPS140=v1.0.0 is set.
Clone()
Returns a copy of the hash with equivalent and independent state.
If cloning is not supported at runtime, returns an error wrapping errors.ErrUnsupported.
Example:
import (
"crypto/sha256"
"fmt"
)
h1 := sha256.New()
h1.Write([]byte("hello "))
// Clone the hash state
h2, err := h1.(hash.Cloner).Clone()
if err != nil {
log.Fatal(err)
}
// Both hashes can continue independently
h1.Write([]byte("world"))
h2.Write([]byte("Go"))
fmt.Printf("h1: %x\n", h1.Sum(nil))
fmt.Printf("h2: %x\n", h2.(hash.Hash).Sum(nil))
XOF Interface
Extendable Output Function (XOF) - a hash with arbitrary or unlimited output length.
type XOF interface {
io.Writer
io.Reader
Reset()
BlockSize() int
}
Write()
Absorbs more data into the XOF’s state. Panics if called after Read.
Read()
Reads more output from the XOF. May return io.EOF if there’s a limit to the output length.
Example with SHAKE256:
import (
"crypto/sha3"
"fmt"
)
xof := sha3.NewShake256()
// Absorb input
xof.Write([]byte("hello world"))
// Read arbitrary length output
output := make([]byte, 64) // Can be any length
xof.Read(output)
fmt.Printf("%x\n", output)
Important: For XOF functions, you must not call Write() after calling Read(). Doing so will cause a panic.
State Marshaling
Hash implementations in the standard library (e.g., hash/crc32, crypto/sha256) implement encoding.BinaryMarshaler, encoding.BinaryAppender, and encoding.BinaryUnmarshaler interfaces.This allows saving and restoring hash state for continuing computation later.
Example:
import (
"crypto/sha256"
"encoding"
"fmt"
)
h1 := sha256.New()
h1.Write([]byte("hello "))
// Save state
marshaler := h1.(encoding.BinaryMarshaler)
state, err := marshaler.MarshalBinary()
if err != nil {
log.Fatal(err)
}
// Continue hashing
h1.Write([]byte("world"))
sum1 := h1.Sum(nil)
// Restore state in new hash
h2 := sha256.New()
unmarshaler := h2.(encoding.BinaryUnmarshaler)
err = unmarshaler.UnmarshalBinary(state)
if err != nil {
log.Fatal(err)
}
// Continue from saved point
h2.Write([]byte("world"))
sum2 := h2.Sum(nil)
fmt.Printf("Equal: %v\n", bytes.Equal(sum1, sum2)) // true
Security Note: Hash state may contain portions of the input in its original form. Handle marshaled state carefully if it contains sensitive data.
Common Hash Functions
Cryptographic Hashes
import "crypto/sha256"
h := sha256.New() // SHA-256
h := sha256.New224() // SHA-224
import "crypto/sha512"
h := sha512.New() // SHA-512
h := sha512.New384() // SHA-384
h := sha512.New512_224() // SHA-512/224
h := sha512.New512_256() // SHA-512/256
import "crypto/sha1"
h := sha1.New() // SHA-1 (deprecated for security)
import "crypto/md5"
h := md5.New() // MD5 (deprecated for security)
import "crypto/sha3"
h := sha3.New224() // SHA3-224
h := sha3.New256() // SHA3-256
h := sha3.New384() // SHA3-384
h := sha3.New512() // SHA3-512
// Extendable-output functions
xof := sha3.NewShake128() // SHAKE128
xof := sha3.NewShake256() // SHAKE256
Non-cryptographic Hashes
import "hash/crc32"
h := crc32.NewIEEE() // CRC-32 IEEE polynomial
import "hash/crc64"
table := crc64.MakeTable(crc64.ISO)
h := crc64.New(table) // CRC-64
Compatibility
The Go project maintains compatibility with encoded hash states across versions. Any released version should be able to decode state data written by any previously released version, subject to security fixes.See the Go 1 compatibility document for more information.
Usage Patterns
Single Pass Hashing
import "crypto/sha256"
data := []byte("data to hash")
h := sha256.New()
h.Write(data)
sum := h.Sum(nil)
Streaming Hashing
import (
"crypto/sha256"
"io"
"os"
)
file, _ := os.Open("large-file.dat")
defer file.Close()
h := sha256.New()
io.Copy(h, file)
sum := h.Sum(nil)
Appending to Existing Slice
import "crypto/sha256"
h := sha256.New()
h.Write([]byte("data"))
// Append hash to existing data
prefix := []byte("HASH:")
result := h.Sum(prefix) // result = "HASH:" + hash bytes
Reusing Hash Object
import "crypto/sha256"
h := sha256.New()
for _, data := range datasets {
h.Reset()
h.Write(data)
sum := h.Sum(nil)
// Process sum...
}
Optimization Tips:
- Block Alignment: Write data in multiples of
BlockSize() for better performance
- Reuse Hash Objects: Call
Reset() instead of creating new hash objects
- Avoid Small Writes: Buffer small writes when possible
- Choose Appropriate Hash: Use CRC32/CRC64 for checksums, SHA-256+ for security
Security Considerations
Hash Function Security:
- Deprecated for Security: MD5 and SHA-1 are cryptographically broken - use SHA-256 or better
- Not for Passwords: Never use hash functions directly for passwords - use bcrypt, scrypt, or argon2
- Collision Resistance: Modern applications should use SHA-256 or SHA-3 family
- Length Extension Attacks: SHA-256 is vulnerable; use HMAC or SHA-3 when this matters
- State Security: Marshaled hash state may contain input data - handle carefully
See Also
- crypto - Common cryptographic constants and hash identifiers
crypto/sha256 - SHA-224 and SHA-256 hash functions
crypto/sha512 - SHA-384, SHA-512, SHA-512/224, and SHA-512/256
crypto/sha3 - SHA-3 family and SHAKE XOF functions
hash/crc32 - 32-bit cyclic redundancy check
hash/crc64 - 64-bit cyclic redundancy check