TOC

Golang SHA 函数

哈希算法(hash)是一种将任意长度数据映射成固定长度数据的方法。有时也叫摘要算法。

有非常多不同的哈希算法,其中最常见的是 md5 和 sha (sha1/sha256/sha512)两种。Golang md5 在 2021/01/14, Go MD5 中已经写过了。这里就记录一下 Golang sha 的使用方法。

// crypto.sha1
func New() hash.Hash
func Sum(data []byte) [Size]byte {
    if boringEnabled {
        return boringSHA1(data)
    }
    var d digest
    d.Reset()
    d.Write(data)
    return d.checkSum()
}
func (d *digest) MarshalBinary() ([]byte, error)
func (d *digest) UnmarshalBinary(b []byte) error
func (d *digest) Reset()
func (d *digest) Size() int
func (d *digest) BlockSize() int
func (d *digest) Write(p []byte) (nn int, err error)
func (d *digest) Sum(in []byte) []byte
func (d *digest) checkSum() [Size]byte
func (d *digest) ConstantTimeSum(in []byte) []byte
func (d *digest) constSum() [Size]byte

// crypto.sha256
func New() hash.Hash
func New224() hash.Hash // sha224
func Sum224(data []byte) [Size224]byte
func Sum256(data []byte) [Size]byte

// crypto.sha512
func New() hash.Hash
func New384() hash.Hash
func New512_224() hash.Hash
func New512_256() hash.Hash
func Sum384(data []byte) [Size384]byte
func Sum512(data []byte) [Size]byte
func Sum512_224(data []byte) [Size224]byte
func Sum512_256(data []byte) [Size256]byte

用法都一样:

h := sha1.New()  // hash.Hash
io.WriteString(h, "His money is twice tainted:")
io.WriteString(h, " 'taint yours and 'taint mine.")
fmt.Printf("% x", h.Sum(nil))
h := sha1.New()
if _, err := io.Copy(h, f); err != nil {
    log.Fatal(err)
}
fmt.Printf("% x", h.Sum(nil))

hash.Hash 接口

type Hash interface {
    io.Writer
    Sum(b []byte) []byte
    Reset()
    Size() int
    BlockSize() int
}

函数

  • sha1.New() -> hash.Hash
  • sha1.Sum(data []byte) -> [Size]byte

  • sha256.New() -> hash.Hash

  • sha256.Sum256(data []byte) -> [Size]byte
  • sha256.New224() -> hash.Hash
  • sha256.Sum224(data []byte) -> [Size224]byte

  • sha512.New() -> hash.Hash

  • sha512.Sum512(data []byte) -> [Size]byte
  • sha512.New384() -> hash.Hash
  • sha512.Sum384(data []byte) -> [Size384]byte
  • sha512.New512_224() -> hash.Hash
  • sha512.Sum512_224(data []byte) -> [Size224]byte
  • sha512.New512_256() -> hash.Hash
  • sha512.Sum512_256(data []byte) -> [Size256]byte
package main

import (
    "crypto/md5"
    "crypto/sha1"
    "crypto/sha256"
    "crypto/sha512"
    "fmt"
    "hash/fnv"
    "io"
    "log"
    "os"
)

func main() {
    filepath := "go.mod"
    f, err := os.Open(filepath)
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    fi, err := f.Stat()
    fmt.Printf("%#v err:%#v\n", fi, err)
    data := make([]byte, fi.Size())
    n, err := f.Read(data)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%d, %#v, err:%#v\n", n, data, err)

    {
        hash := fnv.New32a()
        hash.Write(data)
        result := hash.Sum32()
        fmt.Printf("FNV-1a 32-bit hash: %d\n\n", result)
    }

    {
        fmt.Printf("MD5    : %x\n", md5.Sum(data))
        fmt.Printf("Sha1   : %x\n", sha1.Sum(data))
        fmt.Printf("Sha256 : %x\n", sha256.Sum256(data))
        fmt.Printf("Sha512 : %x\n", sha512.Sum512(data))
    }

    {
        f.Seek(0, 0)
        hasher := md5.New()
        _, err = io.Copy(hasher, f)
        if err != nil {
            log.Fatal(err)
        }
        sum := hasher.Sum(nil)
        fmt.Printf("MD5 2  : %x\n", sum)
    }
}