2013-04-08 34 views
6

我需要爲Windows實用程序,計算SHA256文件校驗,這樣當我下載 的Fedora我可以從這裏覈實校驗和計算SHA256文件校驗:https://fedoraproject.org/static/checksums/Fedora-18-i386-CHECKSUM如何去

http://support.microsoft.com/kb/889768微軟工具只做MD5和SHA1。

我不想使用其他可下載的工具,這些工具沒有被簽名,也不能從https或我不知道的來源獲得,因爲通過未加密的連接或從未加密的連接下載未簽名的代碼沒有任何意義不可信任的來源來驗證另一個代碼的簽名來信任它。

幸運的是,谷歌提供了使用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))) 
} 

如何使它使用流,以便它可以處理任何文件大小。

回答

18

SHA256散列器實現了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) 
} 
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

1

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)) 
}