首页 > 解决方案 > 如何在 Go 中计算一个非常大的文件的 SHA256?

问题描述

我有一个非常大的文件,我需要计算 Go 中的校验和(30 到 200GB 之间)。我已经使用通用sha256sum程序来获取数据的规范散列,但是在尝试在 Go 中做同样的事情时,我无法获得相同的散列。

我最初是从这个功能开始的,它确实按预期工作:

func checksum(file string) (string, error) {
    f, err := os.Open(file)
    if err != nil {
        return "", err
    }

    defer func() {
        _ = f.Close()
    }()

    copyBuf := make([]byte, 1024 * 1024)

    h := sha256.New()
    if _, err := io.CopyBuffer(h, f, copyBuf); err != nil {
        return "", err
    }

    return hex.EncodeToString(h.Sum(nil)), nil
}

但是,需求发生了变化,我需要在读取缓冲区时对其进行一些处理,因此我将代码修改为类似这样。但是,现在哈希不正确,我不确定我做错了什么。

    f, err := os.Open("<large file>")
    if err != nil {
        panic(err)
    }

    defer func() {
        _ = f.Close()
    }()

    buf := make([]byte, 1024 * 1024)
    h := sha256.New()

    for {
        bytesRead, err := f.Read(buf)
        if err != nil {
            if err != io.EOF {
                panic(err)
            }

            fmt.Println("EOF")
            break
        }

        // do some other work with buf before adding it to the hasher
        // processBuffer(buf)

        fmt.Printf("bytes read: %d\n", bytesRead)
        h.Write(buf)
    }

    fmt.Printf("checksum: %s\n", hex.EncodeToString(h.Sum(nil)))

有人知道我做错了什么吗?

标签: go

解决方案


我想到了。我需要在写入之前截断缓冲区:

h.Write(buf[:bytesRead])代替h.Write(buf)


推荐阅读