-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
93 lines (81 loc) · 2.63 KB
/
main.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
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
)
const (
decryptionKey = 0x55
verificationKey = 0x6E
decryptedDirName = "decrypted_bundles"
bundlesPath = "bundles"
)
type FileDecryptor struct {
DecryptedPath string
}
func NewFileDecryptor(bundlesPath string) *FileDecryptor {
decryptedPath := filepath.Join(bundlesPath, decryptedDirName)
if _, err := os.Stat(decryptedPath); os.IsNotExist(err) {
err := os.MkdirAll(decryptedPath, os.ModePerm)
if err != nil {
panic(err)
}
}
return &FileDecryptor{DecryptedPath: decryptedPath}
}
func (fd *FileDecryptor) decryptDataChunk(chunk []byte, key byte) []byte {
decryptedChunk := make([]byte, len(chunk))
for i, b := range chunk {
decryptedChunk[i] = b ^ key
}
return decryptedChunk
}
func (fd *FileDecryptor) decryptFile(inputPath string, outputPath string) error {
inputData, err := ioutil.ReadFile(inputPath)
if err != nil {
return fmt.Errorf("error reading file %s: %v", inputPath, err)
}
key := inputData[0] ^ decryptionKey
if key != inputData[1] ^ verificationKey {
return fmt.Errorf("invalid key")
}
decryptedData := fd.decryptDataChunk(inputData[2:], key)
err = ioutil.WriteFile(outputPath, decryptedData, 0644)
if err != nil {
return fmt.Errorf("error writing file %s: %v", outputPath, err)
}
return nil
}
func (fd *FileDecryptor) decryptBundles() (duration time.Duration, filesDecrypted int, err error) {
startTime := time.Now()
err = filepath.Walk(bundlesPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("error walking through path %s: %v", path, err)
}
if info.IsDir() && info.Name() == decryptedDirName {
return filepath.SkipDir
}
if !info.IsDir() && filepath.Ext(path) == ".dat" {
outputPath := filepath.Join(fd.DecryptedPath, info.Name())
err := fd.decryptFile(path, outputPath)
if err != nil {
return err
}
filesDecrypted++
fmt.Printf("Decrypted %s to %s\n", info.Name(), outputPath)
}
return nil
})
duration = time.Since(startTime)
return
}
func main() {
decryptor := NewFileDecryptor(bundlesPath)
duration, filesDecrypted, err := decryptor.decryptBundles()
rps := float64(filesDecrypted) / duration.Seconds()
fmt.Printf("Decryption completed in %v. Rate: %.2f files/sec\n", duration, rps)
fmt.Println("Press any key to exit")
fmt.Scanln()
}