如何在Go中计算sha256文件校验和

时间:2013-04-08 12:34:21

标签: file io cryptography go sha256

我需要Windows的实用程序来计算sha256文件校验和,以便下载时 fedora我可以从这里验证校验和:https://fedoraproject.org/static/checksums/Fedora-18-i386-CHECKSUM

来自http://support.microsoft.com/kb/889768的Microsoft实用程序仅执行md5和sha1。

我不想使用其他可下载的工具,这些工具没有签名,也没有从https或我不了解的来源获得,因为通过未加密的连接下载未签名的代码或不受信任的下载没有任何意义source来验证另一个代码的签名以信任它。

幸运的是,谷歌提供了使用https进行所有下载的可能性,因此我可以通过安全连接下载Go并从那里开始。

这是一个简单的代码,可以为一个小文件执行此操作,但对于大文件来说这不是很好,因为它不是流式传输。

package main

import (
    "io/ioutil"
    "crypto/sha256"
    "os"
    "log"
    "encoding/hex"
)

func main() {
    hasher := sha256.New()
    s, err := ioutil.ReadFile(os.Args[1])    
    hasher.Write(s)
    if err != nil {
        log.Fatal(err)
    }

    os.Stdout.WriteString(hex.EncodeToString(hasher.Sum(nil)))
}

如何使用流以使其适用于任何文件大小。

3 个答案:

答案 0 :(得分:22)

SHA256 hasher实现io.Writer接口,因此一个选项是使用io.Copy()函数从适当的io.Reader块中复制数据。这样的事情应该做:

f, err := os.Open(os.Args[1])
if err != nil {
    log.Fatal(err)
}
defer f.Close()
if _, err := io.Copy(hasher, f); err != nil {
    log.Fatal(err)
}

答案 1 :(得分:9)

crypto/sha256 godoc实际上有snippet显示如何执行此操作(它与James基本相同):

package main

import (
  "crypto/sha256"
  "fmt"
  "io"
  "log"
  "os"
)

func main() {
  f, err := os.Open("file.txt")
  if err != nil {
    log.Fatal(err)
  }
  defer f.Close()

  h := sha256.New()
  if _, err := io.Copy(h, f); err != nil {
    log.Fatal(err)
  }

  fmt.Printf("%x", h.Sum(nil))
}

答案 2 :(得分:0)

md5sum的完整示例:

func md5sum(filePath string) (result string, err error) {
    file, err := os.Open(filePath)
    if err != nil {
        return
    }
    defer file.Close()

    hash := md5.New()
    _, err = io.Copy(hash, file)
    if err != nil {
        return
    }

    result = hex.EncodeToString(hash.Sum(nil))
    return
}

EncodeToString不会忽略前导0字节,因此fmt.Println(hex.EncodeToString([]byte{0x00, 0x00, 0xA, 0xB, 0xC}))给出 00000a0b0c