在现代软件开发中,数据的完整性和安全性至关重要。MD5(Message Digest Algorithm 5)作为一种广泛使用的哈希算法,能够生成唯一的消息摘要,从而帮助开发者检测数据是否被篡改。在Go语言中,实现MD5校验相对简单,且具有很高的实用性。本文将详细介绍如何在Go语言中实现MD5校验,并提供完整的示例代码,帮助读者快速掌握这一技术。
最近项目中有个需求,就是地图文件下发后,接收方需要文件的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值
// 打开合成文件 complateFile, _ := os.Create("./test.zip") defer complateFile.Close() // 循环分片合成 for i := 0; i < 5; i++ { // ... 省略中间步骤 complateFile.Write(fileBuffer) } // 计算分片md5进行比对 m5 := md5.New() _, _ = io.Copy(m5, complateFile) complateFileMd5 := hex.EncodeToString(m5.Sum(nil)) if complateFileMd5 != originalFileMd5{ fmt.Println("md5验证失败") }
错误原因
在Go中,如果你在合并分片文件的过程中直接使用*os.File(即file指针)来计算MD5,这通常会导致计算错误,原因在于文件指针的位置。当你打开一个文件并开始读取时,文件指针默认位于文件的开头。如果你在合并过程中不重置文件指针,每次读取都会从上次停止的地方开始,而不是从头开始,导致计算的MD5不正确。
解决方案
计算md5前重置文件指针到文件的开头
complateFile.Seek(0,0)
合成文件后重新打开文件进行md5值计算
func(){ complateFile, _ := os.Create("./test.zip") defer complateFile.Close() for i := 0; i < 5; i++ { // ... 省略中间步骤 complateFile.Write(fileBuffer) } }() // 验证文件的完整性 file, _ := os.Open("./test.zip") m5 := md5.New() _, _ = io.Copy(m5, file) complateFileMd5 := hex.EncodeToString(m5.Sum(nil)) if complateFileMd5 != originalFileMd5{ fmt.Println("md5验证失败") }
工具推荐:
在线md5校验工具:https://www.zhanid.com/tool/md5check.html
总结
本文详细介绍了如何在Go语言中实现MD5校验,包括计算文件的MD5值、验证文件完整性以及处理字符串的MD5校验。通过具体的示例代码,读者可以轻松地理解和应用这些技术。MD5校验作为一种基本的安全措施,在数据传输、文件校验等场景中具有广泛的应用。尽管MD5在某些情况下被认为不够安全,但它仍然是一个非常有用的工具,特别是在不需要高强度加密的场合。希望本文能够为您的Go语言开发工作提供有价值的参考。
本文来源于#猫头鹰数据分析,由@蜜芽 整理发布。如若内容造成侵权/违法违规/事实不符,请联系本站客服处理!
该文章观点仅代表作者本人,不代表本站立场。本站不承担相关法律责任。
如若转载,请注明出处:https://www.zhanid.com/biancheng/1636.html