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校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang如何构造最佳随机密码详解

    Golang如何构造最佳随机密码详解

    人们往往有使用同一密码的习惯,为了防止数据库意外泄露/破坏和出于保护用户隐私的目的,下面这篇文章主要给大家介绍了关于Golang如何构造最佳随机密码的相关资料,需要的朋友可以参考下
    2023-01-01
  • gRPC的发布订阅模式及REST接口和超时控制

    gRPC的发布订阅模式及REST接口和超时控制

    这篇文章主要为大家介绍了gRPC的发布订阅模式及REST接口和超时控制,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 详解Golang如何在编译时注入版本信息

    详解Golang如何在编译时注入版本信息

    这篇文章主要为大家详细介绍了Golang如何在编译时实现注入版本信息,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2023-06-06
  • 使用Go添加HTTPS的实现代码示例

    使用Go添加HTTPS的实现代码示例

    这篇文章主要介绍了使用Go添加HTTPS的实现代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • golang中new与make的区别讲解

    golang中new与make的区别讲解

    new只能开辟单个空间,不能为引用类型开辟多个空间,并且new是对类型进行内存的开辟,返回一个指向该内存空间的指针类型,如果使用new去初始化引用数据类型,不是很合适(当然,new一个对象还是可以的),因此就需要用到另一个内置函数make,需要的朋友可以参考下
    2023-01-01
  • Go实现List、Set、Stack、Deque等数据结构的操作方法

    Go实现List、Set、Stack、Deque等数据结构的操作方法

    Go语言团队的一个核心目标是保持语言的简单性,他们认为,如果一个功能可以用简单的组合来实现,那就没有必要把它放进标准库里,本文给大家介绍Go实现List、Set、Stack、Deque等数据结构的操作方法,感兴趣的朋友跟随小编一起看看吧
    2024-12-12
  • 重学Go语言之JSON操作详解

    重学Go语言之JSON操作详解

    JSON的全称是Javascript Object Notation,是一种数据结构化交互的标准协议,这篇文章主要是来和大家介绍一下Go语言中JSON的相关操作,需要的可以参考下
    2023-08-08
  • go语言通过zlib压缩数据的方法

    go语言通过zlib压缩数据的方法

    这篇文章主要介绍了go语言通过zlib压缩数据的方法,实例分析了Go语言中zlib的使用技巧,需要的朋友可以参考下
    2015-03-03
  • Ubuntu18.04 LTS搭建GO语言开发环境过程解析

    Ubuntu18.04 LTS搭建GO语言开发环境过程解析

    这篇文章主要介绍了Ubuntu18.04 LTS搭建GO语言开发环境过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Go语言实现定时器的方法

    Go语言实现定时器的方法

    这篇文章主要介绍了Go语言实现定时器的方法,涉及Go语言时间操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02

最新评论