根据文件大小做区分;小于1G使用 crypto/md5;大于1G使用 github.com/minio/md5-simd
demo 参考:
package main
import (
"bufio"
"crypto/md5"
"flag"
"fmt"
"github.com/minio/md5-simd"
"io"
"os"
"time"
)
// 参考链接:https://pylist.com/t/1456468578
var fileSrc *string = flag.String("file", `E:\app install\adobe-Photoshop-cc2020.zip`, "The file to hash")
const bufferSize = 65536
const distinguishSize = 1073741824 // 1G
// MD5sum returns MD5 checksum of filename
func MD5sum(filename string) (checksum []byte, err error) {
var fileInfo os.FileInfo
if fileInfo, err = os.Stat(filename); err != nil {
return checksum, err
} else if fileInfo.IsDir() {
return checksum, nil
}
var tempFile *os.File
tempFile, err = os.Open(filename)
if err != nil {
return checksum, err
}
defer tempFile.Close()
if fileInfo.Size() < distinguishSize {
hash := md5.New()
for buf, reader := make([]byte, bufferSize), bufio.NewReader(tempFile); ; {
n, err := reader.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return checksum, err
}
hash.Write(buf[:n])
}
checksum = hash.Sum(nil)
} else {
// Create server
server := md5simd.NewServer()
defer server.Close()
// Create hashing object (conforming to hash.Hash)
md5Hash := server.NewHash()
defer md5Hash.Close()
for buf, reader := make([]byte, bufferSize), bufio.NewReader(tempFile); ; {
n, err := reader.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return checksum, err
}
md5Hash.Write(buf[:n])
}
checksum = md5Hash.Sum(nil)
}
return checksum, nil
}
func main() {
flag.Parse()
fmt.Println("Opening file:" + *fileSrc)
t1 := time.Now()
md5sum, _ := MD5sum(*fileSrc)
fmt.Println(md5sum)
tn := time.Since(t1)
fmt.Println("耗时:", tn)
}