1.首先哈希计算是什么?
哈希计算(Hash Calculation)是将任意大小的数据输入(如文件、文本或数字)通过特定的哈希算法转换成固定长度的输出值(称为“哈希值”或“散列值”)的过程。哈希值通常用于快速查找、数据完整性验证、数据加密等应用中。
哈希函数的特点:
- 固定输出长度:无论输入数据的大小如何,哈希算法输出的哈希值长度是固定的。例如,MD5 的哈希值长度是 128 位(16 字节),而 SHA-256 的哈希值长度是 256 位(32 字节)。
- 唯一性(碰撞不易发生):哈希函数应当尽可能避免不同的输入数据产生相同的哈希值(即“碰撞”)。虽然理论上可能发生碰撞,但好的哈希算法使得碰撞几乎不可能发生。
- 快速计算:哈希函数应当能够高效计算,不论输入数据的大小。
- 不可逆:通过哈希值无法反推原始输入数据。哈希值是单向的,不可解密回原始数据。
常见的哈希算法:
- 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通常使用 os 和 io 包来操作文件
我们使用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 的主要方法:
-
Add(delta int):增加等待的计数。通常在启动 goroutine 之前调用,告诉WaitGroup需要等待多少个 goroutine 完成。-
delta可以是正数或负数。每次delta为正时,WaitGroup就增加一个等待的任务;每次delta为负时,就减少一个任务。通常使用Add(1)来增加一个 goroutine。
-
-
Done():表示一个 goroutine 完成了任务。每个 goroutine 完成后都需要调用Done(),减少计数。-
Done()是在 goroutine 内部调用的,通常与defer结合使用,确保即使发生错误,Done()也能被调用。
-
-
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()
}
运行截图:
这样我们就实现了一个简单的并发哈希文件计算器
&spm=1001.2101.3001.5002&articleId=150955785&d=1&t=3&u=ecc4905e696b4d79ad83deb105ba0bc1)
621

被折叠的 条评论
为什么被折叠?



