123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- package main
- import (
- "crypto/sha256"
- "encoding/hex"
- "encoding/json"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "runtime"
- "sync"
- )
- type Fdhashes struct {
- Path string
- Hashes map[string]string
- }
- var hashes map[string]Fdhashes
- var wg sync.WaitGroup
- var mu sync.RWMutex
- func main() {
- runtime.GOMAXPROCS(5)
- hashes = make(map[string]Fdhashes)
- flag.Parse()
- myFile := flag.Arg(0)
- file, err := os.Stat(myFile)
- if os.IsNotExist(err) {
- log.Fatalln("File does not exists:", myFile)
- }
- if file.IsDir() {
- log.Println("start with folder:", myFile)
- processFolder(myFile)
- } else {
- log.Printf("file %s has hash %s\n", myFile, getHash(myFile))
- }
- fmt.Println("waiting")
- wg.Wait()
- log.Println("done")
- }
- func getHash(fileStr string) string {
- f, err := os.Open(fileStr)
- if err != nil {
- log.Fatal(err)
- }
- defer f.Close()
- h := sha256.New()
- if _, err := io.Copy(h, f); err != nil {
- log.Fatal(err)
- }
- return hex.EncodeToString(h.Sum(nil))
- }
- func outputHash(fileStr string) {
- var hashFile Fdhashes
- doHash := true
- defer wg.Done()
- fmt.Print(".")
- dir, fileName := filepath.Split(fileStr)
- if fileName == ".fdhashes3" {
- return
- }
- mu.Lock()
- hashFile, ok := hashes[dir]
- if !ok {
- _, err := os.Stat(dir + ".fdhashes3")
- if os.IsNotExist(err) {
- hashFile = Fdhashes{Path: dir, Hashes: make(map[string]string)}
- } else {
- hashFile = loadHashfile(dir + ".fdhashes3")
- }
- hashes[dir] = hashFile
- saveHashfile(hashFile)
- }
- _, ok = hashFile.Hashes[fileName]
- doHash = !ok
- hashFile = hashes[dir]
- mu.Unlock()
- if doHash {
- hash := getHash(fileStr)
- mu.Lock()
- hashFile.Hashes[fileName] = hash
- saveHashfile(hashFile)
- mu.Unlock()
- log.Printf("file %s has hash %s\n", fileStr, hash)
- }
- }
- func processFolder(folder string) {
- err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
- if !info.IsDir() {
- wg.Add(1)
- go outputHash(path)
- }
- return nil
- })
- if err != nil {
- panic(err)
- }
- }
- func saveHashfile(hashFile Fdhashes) {
- b, err := json.Marshal(hashFile)
- if err != nil {
- fmt.Println(err)
- return
- }
- err = ioutil.WriteFile(hashFile.Path+".fdhashes3", b, 0644)
- if err != nil {
- panic(err)
- }
- }
- func loadHashfile(filename string) Fdhashes {
- file, err := ioutil.ReadFile(filename)
- if err != nil {
- panic(err)
- }
- data := Fdhashes{}
- err = json.Unmarshal([]byte(file), &data)
- if err != nil {
- panic(err)
- }
- return data
- }
|