Go语言中实现MD5校验的示例代码

猫头鹰数据分析 2024-08-14 17:09:09编程技术
172

在现代软件开发中,数据的完整性和安全性至关重要。MD5(Message Digest Algorithm 5)作为一种广泛使用的哈希算法,能够生成唯一的消息摘要,从而帮助开发者检测数据是否被篡改。在Go语言中,实现MD5校验相对简单,且具有很高的实用性。本文将详细介绍如何在Go语言中实现MD5校验,并提供完整的示例代码,帮助读者快速掌握这一技术。

golang.jpg

最近项目中有个需求,就是地图文件下发后,接收方需要文件的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语言开发工作提供有价值的参考。

Go语言 MD5校验
THE END
蜜芽
故事不长,也不难讲,四字概括,毫无意义。

相关推荐

Golang实现时间戳与时区转换的方法详解
在分布式系统和全球化应用中,时间和时区的处理是一个常见且复杂的需求。Go语言(Golang)作为一门高效且易用的编程语言,提供了丰富的标准库来简化时间处理的任务。本文将详细...
2024-12-18 编程技术
165

MD5校验工具:在线快速计算文件MD5哈希值的实用工具
在数字化时代,确保文件的完整性和安全性是至关重要的。站长工具网提供的MD5校验工具是一款在线工具,它能够让用户快速计算文件的MD5哈希值,验证文件的一致性和保障数据传输...
2024-12-14 新闻资讯
358

Go语言开发之json序列化优化技巧
​在 Go 语言开发中,JSON(JavaScript Object Notation)因其简洁和广泛的兼容性,通常被用作数据交换的主要序列化格式。然而,当你深入使用 JSON 时,可能会发现它并不总是...
2024-11-29 编程技术
158

如何用Go语言搭建WebSocket服务器
在现代Web开发中,WebSocket协议因其能够实现实时双向通信而受到广泛关注。Go语言(也称为Golang)作为一种高性能、并发能力强的编程语言,非常适合用于搭建WebSocket服务器。本...
2024-11-10 编程技术
160

如何在 Golang 中高效检查字符串是否存在于数组中
在 Go 语言(Golang)的编程实践中,经常会遇到需要判断一个字符串是否存在于一个字符串数组中的情况。这种需求在各种应用场景中都很常见,例如文本处理、数据验证、配置管理等...
2024-10-08 编程技术
195

Golang项目配置管理神器之viper的介绍与使用详解
在这篇文章中,我们将深入探讨Viper,一个广受欢迎的Golang项目配置管理神器。Viper不仅支持多来源、多格式的配置读取,还提供了强大的配置热更新功能,使得开发者可以更加灵...
2024-09-29 编程技术
169