-
Notifications
You must be signed in to change notification settings - Fork 0
/
checksum.go
127 lines (107 loc) · 3.25 KB
/
checksum.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"bufio"
"crypto/md5"
"crypto/sha1"
"encoding/csv"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/cheggaaa/pb/v3"
)
func calculateHashes(filePath string) (string, string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", "", err
}
defer file.Close()
sha1Hash := sha1.New()
md5Hash := md5.New()
if _, err := io.CopyBuffer(sha1Hash, file, nil); err != nil {
return "", "", err
}
// Reset file pointer before calculating MD5 hash
if _, err := file.Seek(0, io.SeekStart); err != nil {
return "", "", err
}
if _, err := io.CopyBuffer(md5Hash, file, nil); err != nil {
return "", "", err
}
return fmt.Sprintf("%x", sha1Hash.Sum(nil)), fmt.Sprintf("%x", md5Hash.Sum(nil)), nil
}
func getFileInfo(filePath string) (string, string, int64, string, string, error) {
fileInfo, err := os.Stat(filePath)
if err != nil {
return "", "", 0, "", "", err
}
fileName := filepath.Base(filePath)
fileSize := fileInfo.Size()
fileExtension := filepath.Ext(fileName)
createdDate := fileInfo.ModTime().Format("2024-04-09 15:04:05")
return fileName, filePath, fileSize, fileExtension, createdDate, nil
}
func main() {
var rootFolder string
if len(os.Args) > 1 {
// If command-line argument is provided, use it as root folder
rootFolder = os.Args[1]
} else {
// If no command-line argument is provided, prompt user to enter root folder
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter the folder path: ")
rootFolder, _ = reader.ReadString('\n')
rootFolder = strings.TrimSpace(rootFolder)
}
outputCSV, err := os.Create(filepath.Join(rootFolder, "checksumsha1.csv"))
if err != nil {
fmt.Println("Error creating output CSV file:", err)
return
}
defer outputCSV.Close()
writer := csv.NewWriter(outputCSV)
defer writer.Flush()
err = writer.Write([]string{"Filename", "File Path", "SHA1 Hash", "MD5 Hash", "File Size", "File Extension", "Created Date"})
if err != nil {
fmt.Println("Error writing CSV header:", err)
return
}
files := make([]string, 0)
err = filepath.Walk(rootFolder, func(filePath string, fileInfo os.FileInfo, err error) error {
if err != nil {
return err
}
if !fileInfo.IsDir() {
files = append(files, filePath)
}
return nil
})
if err != nil {
fmt.Println("Error, no folder path was entered.", err)
return
}
bar := pb.StartNew(len(files))
bar.Set(pb.Bytes, true)
bar.SetTemplateString(`Processing digital objects and currently at the following percent: {{percent . }}`)
for _, filePath := range files {
sha1Hash, md5Hash, err := calculateHashes(filePath)
if err != nil {
fmt.Println("Error calculating hashes:", err)
return
}
fileName, filePath, fileSize, fileExtension, createdDate, err := getFileInfo(filePath)
if err != nil {
fmt.Println("Error getting file info:", err)
return
}
err = writer.Write([]string{fileName, filePath, sha1Hash, md5Hash, fmt.Sprint(fileSize), fileExtension, createdDate})
if err != nil {
fmt.Println("Error writing to CSV:", err)
return
}
bar.Increment()
}
bar.Finish()
fmt.Println("Checksums and file information are stored in the folder where the program was run.")
}