哈希算法(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)
}
}