app.App.__repr__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
"""
2
An python script to compare multiple hash with a dictionary of word.
3
4
:argument:
5
--help			Show this helpful message
6
7
:param[1]:		Hash path,	default: [assets/hash]
8
:param[2]:		Dictionary	path, default: [assets/dict]
9
"""
10
import os
11
from time import perf_counter
12
from hashlib import sha256
13
14
from os import listdir, path
15
from sys import argv
16
from typing import Optional, List, Dict
17
18
__version__: str = "1.0"
19
__author__: str = "Yohann Boniface"
20
21
22
class App:
23
24
    def __init__(
25
        self,
26
        all_hash: str = "assets/hash",
27
        dictionary: str = "assets/dict",
28
        *overflow: str
29
    ):
30
        """Initialize the application with given sys argy."""
31
        print_ascii_art()
32
33
        if overflow or '--help' in argv:
34
            print(self)
35
            os.system("pause")
36
            return
37
38
        self.all_hash: List[str] = self.get_content(all_hash)
39
        self.dictionary: List[str] = self.get_content(dictionary)
40
41
        if self.all_hash is None or self.dictionary is None:
42
            print("File or Directory not found !", self)
43
            return
44
45
        print(' results '.center(32, '-'))
46
        self.run()
47
48
    def __repr__(self):
49
        """Representation give the help message."""
50
        return '\n'.join((
51
            "archive - This is the help message.",
52
            "--help\t\t\tShow this helpful message", '',
53
            "@param[1]:\t\tHash path,\tdefault: [assets/hash]",
54
            "@param[2]:\t\tDictionary\tpath, default: [assets/dict]"
55
        ))
56
57
    def run(self):
58
        """Start the hash brute force process."""
59
        if len(self.all_hash) != 1:
60
            self.multiple(self.all_hash)
61
62
        else:
63
            self.single(self.all_hash[0])
64
65
        os.system("pause")
66
67
    def single(self, _hash: str) -> None:
68
        """Scroll within the dictionary until a hash matches."""
69
        for val in self.dictionary:
70
            if self.get_hash(val) == _hash:
71
                self.log(f"Found matching hash for {val} ({_hash})")
72
                break
73
        else:
74
            self.log("<!> No hash found")
75
76
    def multiple(self, _hash_list: List[str]) -> None:
77
        """Build a hash dictionary or proceed multiple hash lookup."""
78
79
        self.dictionary: Dict[str, str] = {
80
            self.get_hash(val): val for val in self.dictionary
81
        }
82
83
        for _hash in _hash_list:
84
            val: Optional[str] = self.dictionary.get(_hash)
85
86
            self.log(
87
                "<!> No hash found"
88
                if val is None else f"Found matching hash for {val} ({_hash})"
89
            )
90
91
    def get_content(self, _path: str) -> Optional[List[str]]:
92
        """Get the files contents of a given file or directory."""
93
        if path.isfile(_path):
94
            return self.read_single_file(_path)
95
96
        if path.isdir(_path):
97
            return self.read_folder_files(_path)
98
99
    @staticmethod
100
    def get_hash(string) -> str:
101
        """Return the sh256 hash of a string."""
102
        return sha256(string.encode()).hexdigest()
103
104
    @staticmethod
105
    def log(string: str) -> None:
106
        """Prints a formatted log with a time marker."""
107
        print(f"[{perf_counter():,.3f}s] {string}")
108
109
    @staticmethod
110
    def read_single_file(_path: str) -> List[str]:
111
        """Read lines from a given file path."""
112
        print(f"Opening file: {_path}")
113
114
        with open(_path) as f:
115
            return f.read().splitlines()
116
117
    @staticmethod
118
    def read_folder_files(_path: str) -> List[str]:
119
        """Read multiple files from a folder and merge there lines."""
120
        files: List[List[str]] = []
121
        print(f"Opening folder: {_path}")
122
123
        for filename in listdir(_path):
124
            if not filename.endswith('.txt'):
125
                continue
126
127
            print(f"+ {filename}")
128
129
            with open(f"{_path}/{filename}") as f:
130
                files.append(f.read().splitlines())
131
132
        return [line for file in files for line in file]
133
134
135
def print_ascii_art() -> None:
136
    """Prints the school ascci art in the console."""
137
    with open('assets/asciiart/asciiart.txt') as f:
138
        print(f.read())
139
140
141
if __name__ == '__main__':
142
    App(*argv[1:])
143