前言
最近项目中有个需求,就是地图文件下发后,接收方需要文件的md5值,和接收到的文件做比对,以免文件不完整,引起bug,于是测试了下本地文件和远程文件的md5计算。
1、本地文件
要获取指定本地文件的md5值,你可以使用crypto/md5包来计算文件的md5散列值。以下是一个示例代码,演示了如何打开一个文件并计算其md5值:
package main import ( "crypto/md5" "encoding/hex" "fmt" "io" "net/http" "os" ) func main() { md5bylocalfile() } func md5bylocalfile() { // // 指定文件路径 filepath := "d:/code/000fa28f-c114-49fe-9699-8c7f8b2eb222.png" // filepath := "https://minio.dev.inrobot.cloud/map/000fa28f-c114-49fe-9699-8c7f8b2eb222.png" // 打开文件 file, err := os.open(filepath) if err != nil { fmt.println("failed to open file:", err) return } defer file.close() // 创建一个md5哈希对象 hasher := md5.new() // 将文件内容读入哈希对象 if _, err := io.copy(hasher, file); err != nil { fmt.println("failed to read file:", err) return } // 计算并获取哈希值 hashbytes := hasher.sum(nil) // 将哈希值转换为十六进制字符串 hashstring := hex.encodetostring(hashbytes) // 输出md5哈希值 fmt.println("md5 hash of the file:", hashstring) }
输出结果如下:
ps d:\gostudy2022\timescheduler\md5> go run .\main.go
localfile md5 hash of the file: b4735b024f3552b1277671303149719b
2、远程文件
远程文件其实就是网络中可访问的资源文件,要获取指定网络地址的文件的md5值,你需要先下载文件的内容到内存或磁盘上,然后再计算其md5值。这里我展示一个示例,该示例使用net/http包来下载文件,并使用crypto/md5包来计算md5值。以下是完整的示例代码:
package main import ( "crypto/md5" "encoding/hex" "fmt" "io" "net/http" "os" ) func main() { md5byremotefile() } func md5byremotefile() { // 指定文件的url url := "https://minio.dev.inrobot.cloud/map/000fa28f-c114-49fe-9699-8c7f8b2eb222.png" // 发起http get请求 resp, err := http.get(url) if err != nil { fmt.println("failed to fetch file:", err) return } defer resp.body.close() // 检查响应状态码 if resp.statuscode != http.statusok { fmt.printf("failed to fetch file: http status code %d\n", resp.statuscode) return } // 创建一个md5哈希对象 hasher := md5.new() // 将文件内容读入哈希对象 if _, err := io.copy(hasher, resp.body); err != nil { fmt.println("failed to read file:", err) return } // 计算并获取哈希值 hashbytes := hasher.sum(nil) // 将哈希值转换为十六进制字符串 hashstring := hex.encodetostring(hashbytes) // 输出md5哈希值 fmt.println("md5 hash of the file:", hashstring) }
这里远程文件和上例的文件相同,输出结果如下:
ps d:\gostudy2022\timescheduler\md5> go run .\main.go
remotefile md5 hash of the file: b4735b024f3552b1277671303149719b
可以看到,本地文件和远程文件的md5值是相同的,从而在项目中,我们可以根据md5值是否相同,判断文件是不是同一个文件,有没有被损坏或篡改。
拓展:golang 计算md5值
代码
//md5 func md5smallfile(path string) (string, error) { file, err := os.open(path) if err != nil { return "", err } defer file.close() h := md5.new() _, err = io.copy(h, file) if err != nil { return "", err } return hex.encodetostring(h.sum(nil)), nil } func md5bigfile(path string) (string, error) { var filechunk uint64 = 10485760 file, err := os.open(path) if err != nil { return "", err } defer file.close() // calculate the file size info, _ := file.stat() filesize := info.size() blocks := uint64(math.ceil(float64(filesize) / float64(filechunk))) h := md5.new() for i := uint64(0); i < blocks; i++ { blocksize := int(math.min(float64(filechunk), float64(filesize-int64(i*filechunk)))) buf := make([]byte, blocksize) _, err := file.read(buf) if err != nil { return "", err } _, err = io.writestring(h, string(buf)) // append into the hash if err != nil { return "", err } } return hex.encodetostring(h.sum(nil)), nil } func md5string(v string) string { d := []byte(v) m := md5.new() m.write(d) return hex.encodetostring(m.sum(nil)) }
md5.new()返回一个 hash.hash 对象
hash.hash对象定义了一个sum接口,其原型为:
func sum(data []byte) [size]byte
sum()对hash.hash对象内部存储的内容进行校验计算,然后将其追加到data的后面形成一个新的byte切片,所以一般需要将data设为nil。
到此这篇关于golang实现md5校验的代码示例的文章就介绍到这了,更多相关golang md5校验内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论