Golang实现Md5校验的代码示例

 更新时间:2024年07月28日 14:09:46   作者:猫头鹰数据分析  
最近项目中有个需求,就是地图文件下发后,接收方需要文件的md5值,和接收到的文件做比对,以免文件不完整,引起bug,于是测试了下本地文件和远程文件的md5计算,所以本文给大家介绍了Golang实现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 
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校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言的队列和堆栈实现方法

    Go语言的队列和堆栈实现方法

    这篇文章主要介绍了Go语言的队列和堆栈实现方法,涉及container/list包的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Golang获取当前时间代码

    Golang获取当前时间代码

    本文给大家汇总介绍了golang中的相关的时间的操作,有需要的小伙伴可以拿走参考下
    2018-10-10
  • 如何用go-zero 实现中台系统

    如何用go-zero 实现中台系统

    这篇文章主要介绍了如何用go-zero 实现中台系统,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 浅谈go-restful框架的使用和实现

    浅谈go-restful框架的使用和实现

    这篇文章主要介绍了浅谈go-restful框架的使用和实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 在 Go 语言中使用 regexp 包处理正则表达式的操作

    在 Go 语言中使用 regexp 包处理正则表达式的操作

    正则表达式是处理字符串时一个非常强大的工具,而 Go 语言的 regexp 包提供了简单而强大的接口来使用正则表达式,本文将介绍如何在 Go 中使用 regexp 包来编译和执行正则表达式,以及如何从文本中匹配和提取信息,感兴趣的朋友一起看看吧
    2023-12-12
  • go调用shell命令两种方式实现(有无返回值)

    go调用shell命令两种方式实现(有无返回值)

    本文主要介绍了go调用shell命令两种方式实现(有无返回值),主要用于执行shell命令,并且返回shell的标准输出,具有一定的参考价值,感兴趣的可以了解一下
    2021-12-12
  • Go语言中的包Package详解

    Go语言中的包Package详解

    本文详细讲解了Go语言中的包Package,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • go货币计算时如何避免浮点数精度问题

    go货币计算时如何避免浮点数精度问题

    在开发的初始阶段,我们经常会遇到“浮点数精度”和“货币值表示”的问题,那么在golang中如何避免这一方面的问题呢,下面就跟随小编一起来学习一下吧
    2024-02-02
  • 源码分析Go语言使用cgo导致线程增长的原因

    源码分析Go语言使用cgo导致线程增长的原因

    这篇文章主要从一个cgo调用开始解析Go语言源码,从而分析一下造成线程增长的原因,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一学习一下
    2023-06-06
  • 使用Golang的singleflight防止缓存击穿的方法

    使用Golang的singleflight防止缓存击穿的方法

    这篇文章主要介绍了使用Golang的singleflight防止缓存击穿的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04

最新评论