并发txt文件哈希器( goroutine 计算 md5/sha256)

1.首先哈希计算是什么?

哈希计算(Hash Calculation)是将任意大小的数据输入(如文件、文本或数字)通过特定的哈希算法转换成固定长度的输出值(称为“哈希值”或“散列值”)的过程。哈希值通常用于快速查找、数据完整性验证、数据加密等应用中。

哈希函数的特点:

  1. 固定输出长度:无论输入数据的大小如何,哈希算法输出的哈希值长度是固定的。例如,MD5 的哈希值长度是 128 位(16 字节),而 SHA-256 的哈希值长度是 256 位(32 字节)。
  2. 唯一性(碰撞不易发生):哈希函数应当尽可能避免不同的输入数据产生相同的哈希值(即“碰撞”)。虽然理论上可能发生碰撞,但好的哈希算法使得碰撞几乎不可能发生。
  3. 快速计算:哈希函数应当能够高效计算,不论输入数据的大小。
  4. 不可逆:通过哈希值无法反推原始输入数据。哈希值是单向的,不可解密回原始数据。

常见的哈希算法:

  • MD5(Message Digest Algorithm 5):产生 128 位(16 字节)的哈希值。广泛应用于文件校验和数字签名,但已被证明存在碰撞漏洞,因此不再推荐用于安全领域。
  • SHA-1(Secure Hash Algorithm 1):产生 160 位(20 字节)的哈希值。它曾广泛应用,但由于存在安全性问题,也不再推荐用于安全应用。
  • SHA-256:属于 SHA-2 家族,产生 256 位(32 字节)的哈希值,安全性更高,广泛用于区块链等安全敏感的场景。

2.实现并发txt文件计算哈希

1.读取文件在go通常使用 osio 包来操作文件

我们使用os包

os.Open()来打开txt

2.定义结构体

type file struct {
	path   string
	md5tye string
}

3.定义函数

func readTxt(f *file, wg *sync.WaitGroup) {
	defer wg.Done() // 完成时通知 WaitGroup
	file, err := os.Open(f.path)
	if err != nil {
		fmt.Println(err)
	}
	defer file.Close()
	var hash io.Writer
	if f.md5tye == "md5" {
		hash = md5.New()
	} else {
		hash = sha256.New()
	}
	_, err = io.Copy(hash, file)
	fmt.Printf("%s (%s): %x\n", f.path, f.md5tye, hash)
}

由于是并发,我们主函数应等待所有goroutine完成后结束 所以我们用到了sync.WaitGroup

ps:sync.WaitGroup是 Go 语言中的一种同步工具,用于等待一组 goroutine 完成。它通过计数的方式来管理并发任务的完成,并确保主程序或其他 goroutine 在所有任务完成之前不会继续执行。这在并发编程中非常有用,尤其是在你启动多个 goroutine 时,可以确保在所有 goroutine 完成任务后再执行后续的操作

 

sync.WaitGroup 的主要方法:

  1. Add(delta int):增加等待的计数。通常在启动 goroutine 之前调用,告诉 WaitGroup 需要等待多少个 goroutine 完成。

    • delta 可以是正数或负数。每次 delta 为正时,WaitGroup 就增加一个等待的任务;每次 delta 为负时,就减少一个任务。通常使用 Add(1) 来增加一个 goroutine。

  2. Done():表示一个 goroutine 完成了任务。每个 goroutine 完成后都需要调用 Done(),减少计数。

    • Done() 是在 goroutine 内部调用的,通常与 defer 结合使用,确保即使发生错误,Done() 也能被调用。

  3. Wait():阻塞当前的 goroutine,直到 WaitGroup 中的所有任务都完成。它会等待所有 goroutine 执行完毕后才会继续执行后续的代码。

    • 这个方法通常在主程序或者需要等待多个 goroutine 完成的地方调用。

完整代码:

package main

import (
	"crypto/md5"
	"crypto/sha256"
	"fmt"
	"io"
	"os"
	"sync"
)

type file struct {
	path   string
	md5tye string
}

func readTxt(f *file, wg *sync.WaitGroup) {
	defer wg.Done() // 完成时通知 WaitGroup
	file, err := os.Open(f.path)
	if err != nil {
		fmt.Println(err)
	}
	defer file.Close()
	var hash io.Writer
	if f.md5tye == "md5" {
		hash = md5.New()
	} else {
		hash = sha256.New()
	}
	_, err = io.Copy(hash, file)
	fmt.Printf("%s (%s): %x\n", f.path, f.md5tye, hash)
}
func main() {
	var wg sync.WaitGroup
	fileList := []file{
		{"file/1.txt", "md5"},
		{"file/2.txt", "sha256"},
		{"file/3.txt", "md5"},
	}
	for _, file := range fileList {
		wg.Add(1)
		go readTxt(&file, &wg)
	}
	wg.Wait()
}

运行截图:

这样我们就实现了一个简单的并发哈希文件计算器

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值