Skip to content

Commit 6dfe078

Browse files
committed
Fix major bugs, major improvements in flag tasks and improve error handling
1 parent ef332d4 commit 6dfe078

File tree

5 files changed

+44
-66
lines changed

5 files changed

+44
-66
lines changed

project/__main__.py

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
description='A tool to Encrypt, Decrypt texts with a substitution cipher given as the key')
77

88
# -e & --encrypt
9-
parser.add_argument('-e', '--encrypt', nargs='+',
10-
metavar='PLAIN', help='Encrypt the plain text', type=str)
9+
parser.add_argument('-e', '--encrypt', nargs='?',
10+
metavar='PLAIN', help='Encrypt the plain text', type=str, default=False, const=True)
1111
# -d & --decrypt
12-
parser.add_argument('-d', '--decrypt', nargs='+', metavar='CIPHER',
13-
help='Decrypt the cipher text', type=str)
12+
parser.add_argument('-d', '--decrypt', nargs='?', metavar='CIPHER',
13+
help='Decrypt the cipher text', type=str, default=False, const=True)
1414
# -k & --key
1515
parser.add_argument('-k', '--key', nargs=1, metavar='KEY',
1616
help='Represents the number of places for the shift', type=int, default=False)
@@ -20,34 +20,31 @@
2020
parser.add_argument('-o', '--output', nargs=1, type=str,
2121
help='Output file directory')
2222
# -s & --source
23-
parser.add_argument('-sf', '--sourceFile', action='store_true')
23+
parser.add_argument('-sf', '--sourceFile', nargs=1, metavar='PATH',
24+
help='Path to the file containing message to cipher', type=str)
2425

2526
# -b & --brute
26-
parser.add_argument('-br', '--bruteforce', nargs='+',
27-
metavar='PLAIN', help='Cipher text to crack', type=str)
27+
parser.add_argument('-br', '--bruteforce', nargs='?',
28+
metavar='PLAIN', help='Cipher text to crack', type=str, default=False, const=True)
2829

2930
# -fr & --freq-analysis
30-
parser.add_argument('-fr', '--freq-analysis', nargs='+', metavar='CIPHER',
31-
help='Plain text to crack by analysing', type=str)
31+
parser.add_argument('-fr', '--freq-analysis', nargs='?', metavar='CIPHER',
32+
help='Plain text to crack by analysing', type=str, default=False, const=True)
3233

3334
# -w & --wordlist
3435
parser.add_argument('-w', '--wordlist', nargs=1, metavar='WORDLIST',
3536
help='Path to the wordlist containing language words', type=str)
3637

3738
# -bfr & --brute-frequency
38-
parser.add_argument('-bfr', '--brute-frequency', nargs='+', metavar='CIPHER',
39-
help='Cipher to crack and analyse output for the text containing words in a wordlist')
39+
parser.add_argument('-bfr', '--brute-frequency', nargs='?', metavar='CIPHER',
40+
help='Cipher to crack and analyse output for the text containing words in a wordlist', default=False, const=True)
4041

4142
args = parser.parse_args()
4243

4344

4445
def handle_args():
4546
try:
46-
# If key isn't in the args,
47-
if not args.key and (args.encrypt or args.decrypt):
48-
raise NameError("Key is not defined")
49-
# If brute frequency flag used,
50-
elif args.brute_frequency:
47+
if args.brute_frequency:
5148
brute_freq_handler(args)
5249
# If frequency flag used,
5350
elif args.freq_analysis:

project/crack.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
from .crypt import ALPHEBET, decrypt
22
from .utils import analyse_text
33
from operator import itemgetter
4+
from colorama import Fore, Style
45
import re
56

67

78
def bruteforce(text):
89
cracked = []
910
# Iterate from 1 to length of the ALPHEBET
1011
for i in range(1, len(ALPHEBET)):
11-
cracked.append('Result with key ' + str(i) + ' ' + decrypt(text, i))
12+
cracked.append(f'{Fore.GREEN}{str(i)}{Style.RESET_ALL} : {decrypt(text, i)}')
1213
return cracked
1314

1415

@@ -25,5 +26,5 @@ def brute_freq(text, wordlist):
2526
avg = float(matches) / len(text.split(' ')) * 100
2627
analysed[text] = avg
2728
# Sort the analysed texts by average
28-
analysed = dict(sorted(analysed.items(), key=itemgetter(1), reverse=True))
29-
return analysed
29+
sorted_analysed = dict(sorted(analysed.items(), key=itemgetter(1), reverse=True))
30+
return [sorted_analysed, analysed]

project/crypt.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ def encrypt(plain_text, key):
2121
ciphered = ALPHEBET[ALPHEBET.find(lower_i) + key]
2222
# If the letter is an uppercase,
2323
# cipher letter will be uppercased too
24-
if i.isupper():
25-
cipher += ciphered.upper()
26-
else:
27-
cipher += ciphered
24+
cipher += ciphered.upper() if i.isupper() else ciphered
2825
# If letter doesn't occur in the ALPHEBET,
2926
# the plain letter will be added to the cipher text
3027
else:
@@ -47,10 +44,7 @@ def decrypt(cipher_text, key):
4744
decrypted = ALPHEBET[ALPHEBET.find(lower_i) - key]
4845
# If the letter is an uppercase,
4946
# decrypted letter will be uppercased too
50-
if i.isupper():
51-
plain += decrypted.upper()
52-
else:
53-
plain += decrypted
47+
plain += decrypted.upper() if i.isupper() else decrypted
5448
# If letter doesn't occur in the ALPHEBET,
5549
# the plain letter will be added to the plain text
5650
else:

project/handlers.py

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
from .crack import bruteforce, brute_freq
2-
from .utils import write_file, analyse_text
2+
from .utils import write_file, analyse_text, get_text
33
from .crypt import encrypt, decrypt
44
from colorama import Fore, Style
55
import re
66

77

88
def bruteforce_handler(args):
9-
c_value = ' '.join(args.bruteforce)
10-
cracked = []
11-
if args.sourceFile:
12-
f = open(c_value, 'r').read()
13-
cracked = bruteforce(f)
14-
else:
15-
cracked = bruteforce(c_value)
9+
# Get all possibilities of the cipher text
10+
cracked = bruteforce(get_text(args, 'bruteforce'))
1611
# Write to the file,
1712
# If an output path specified
1813
if args.output:
@@ -24,18 +19,9 @@ def bruteforce_handler(args):
2419

2520
def encrypt_handler(args):
2621
# Extract key as an int from args
27-
key = int(''.join(map(str, args.key)))
28-
key *= -1 if args.backwards else 1
29-
# Get plain text
30-
e_value = ' '.join(args.encrypt)
31-
# If source presents,
32-
# file content will be encrypted
33-
cipher = ''
34-
if args.sourceFile:
35-
f = open(e_value, 'r').read()
36-
cipher = encrypt(f, key)
37-
else:
38-
cipher = encrypt(e_value, key)
22+
key = int(''.join(map(str, args.key))) * -1 if args.backwards else 1
23+
# Get Cipher text
24+
cipher = encrypt(get_text(args, 'encrypt'), key)
3925
# Write to the file,
4026
# If an output path specified
4127
if args.output:
@@ -46,18 +32,9 @@ def encrypt_handler(args):
4632

4733
def decrypt_handler(args):
4834
# Extract key as an int from args
49-
key = int(''.join(map(str, args.key)))
50-
key *= -1 if args.backwards else 1
51-
# Get Cipher text
52-
d_value = ' '.join(args.decrypt)
53-
# If source presents,
54-
# file content will be decrypted
55-
plain = ''
56-
if args.sourceFile:
57-
f = open(d_value, 'r').read()
58-
plain = decrypt(f, key)
59-
else:
60-
plain = decrypt(d_value, key)
35+
key = int(''.join(map(str, args.key))) * -1 if args.backwards else 1
36+
# Get plain text
37+
plain = decrypt(get_text(args, 'decrypt'), key)
6138
# Write to the file,
6239
# If an output path specified
6340
if args.output:
@@ -70,10 +47,8 @@ def freq_analysis_handler(args):
7047
# Check for missing arguments
7148
if not args.wordlist:
7249
raise ValueError("No Wordlist Found")
73-
text = ''
74-
a_value = ' '.join(args.freq_analysis)
7550
# Filter letters, numbers and spaces
76-
text = re.sub(r'[^A-Za-z0-9 ]+', '', a_value)
51+
text = re.sub(r'[^A-Za-z0-9 ]+', '', get_text(args, 'freq_analysis'))
7752
# Analyse the frequency
7853
matches = analyse_text(text, ''.join(args.wordlist))
7954
avg = float(matches) / len(text.split(' ')) * 100
@@ -84,11 +59,14 @@ def freq_analysis_handler(args):
8459

8560

8661
def brute_freq_handler(args):
87-
c_value = ' '.join(args.brute_frequency)
62+
# Check for missing arguments
63+
if not args.wordlist:
64+
raise ValueError("No Wordlist Found")
8865
# Get cipher text
89-
cipher = open(c_value, 'r').read() if args.sourceFile else c_value
66+
cipher = get_text(args, 'brute_frequency')
9067
# Get analysed disctionary
91-
analyzed = brute_freq(cipher, ''.join(args.wordlist))
68+
bruteforced = brute_freq(cipher, ''.join(args.wordlist))
69+
analyzed = bruteforced[0]
9270
# Write to the file,
9371
# If an output path specified
9472
if args.output:
@@ -105,7 +83,8 @@ def brute_freq_handler(args):
10583
found = False
10684
for i in analyzed:
10785
if analyzed[i] > 60:
108-
print(f'{Fore.GREEN}{round(analyzed[i], 1)}%{Style.RESET_ALL} : {i}')
86+
print(
87+
f'{Fore.GREEN}{round(analyzed[i], 1)}%{Style.RESET_ALL}: {Fore.CYAN}{list(bruteforced[1].keys()).index(i)}{Style.RESET_ALL} : {i}')
10988
found = True
11089
if not found:
11190
print(

project/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,10 @@ def analyse_text(text, wordlist_path):
2929
if word in wordlist:
3030
matches += 1
3131
return matches
32+
33+
34+
def get_text(args, prop):
35+
if args.sourceFile:
36+
return open(' '.join(args.sourceFile), 'r').read()
37+
else:
38+
return ''.join(vars(args)[prop])

0 commit comments

Comments
 (0)