This is my final version of my simpel Decrypter/Encryptor called Dencryptor. This is one of my first Python projects and I think it turned out pretty good. I am using a Caesar cipher right now and I think it is working as intended. I may try to add some other ciphers to it but I think it is working good right now. This was just a project to learn from and the encryption isn't strong so I do not recommend any one actually using this for anything.
List of commands:
- help - Show this page.
- encrypt {text} - Encrypt some text
- key - Displays your current decryption key
- key {key} - Set a decryption key
- decrypt {text} - Decrypt some text
- exit - close application
What do you guys think about it? Any changes required?
Special thanks to: @Coal_ and @henje for helping!
import secrets
import string
print(""" _____ _
| __ \ | |
| | | | ___ _ __ ___ _ __ _ _ _ __ | |_ ___ _ __
| | | |/ _ \ '_ \ / __| '__| | | | '_ \| __/ _ \ '__|
| |__| | __/ | | | (__| | | |_| | |_) | || __/ |
|_____/ \___|_| |_|\___|_| \__, | .__/ \__\___|_|
__/ | |
|___/|_| """)
userinput = ''
exit = False
key = None
characters = list(string.printable)[:-5]
def get_int(prompt):
try:
return int(prompt)
except ValueError:
print("Input requires a number!")
def encrypt(args, key):
text = []
encryptlist = []
try:
for line in args:
text.extend(line)
for x in range(len(text)):
index = characters.index(text[x])
newindex = (index + key) % len(characters)
cipher = characters[newindex]
encryptlist.append(cipher)
x += 1
encrypted = ''.join(encryptlist)
return encrypted
except ValueError:
print('Invalid character(s)!')
def decrypt(args, key):
text = []
decryptlist = []
try:
for line in args:
text.extend(line)
for x in range(len(text)):
index = characters.index(text[x])
newindex = (index - key) % len(characters)
cipher = characters[newindex]
decryptlist.append(cipher)
x += 1
decrypted = ''.join(decryptlist)
return decrypted
except ValueError:
print('Invalid character(s)!')
while not exit:
arguments = ''
userinput = input('> ')
command = userinput.split(' ', 1)[0]
if userinput != command:
arguments = userinput.split(' ', 1)[1]
if userinput == 'help':
print('''
Dencrypter commands
------------------------------------------
help - Show this page.
encrypt {text} - Encrypt some text
key - Displays your current decryption key
key {key} - Set a decryption key
decrypt {text} - Decrypt some text
exit - close application
''')
if userinput == 'exit':
exit = True
elif command == 'encrypt':
encryptionkey = secrets.randbits(10)
encryption = encrypt(arguments, encryptionkey)
if arguments != '':
if encryption is not None:
print('Encrypted tekst: ' + encryption)
print('Encryption key: ' + str(encryptionkey))
else:
print('The encrypt command requires an argument. \nUse like this: encrypt {text}')
elif command == 'key':
if arguments != '':
key = get_int(arguments)
if key is not None:
print('Decryption key changed to: ' + str(key))
else:
print('Decryption key: ' + str(key))
elif command == 'decrypt':
if arguments != '':
print('Decrypted tekst: ' + decrypt(arguments, key))
print('Using decryption key: ' + str(key))
else:
print('The decrypt command requires an argument. \nUse like this: decrypt {tekst}')
1 Answer 1
It's a nice program, intuitively usable and good if you don't have any cryptographically versed attacker.
When I tried it, my session looked like this:
> encrypt Hello
Encrypted text: (ELLO
Encryption key: 311
> decrypt (ELLO
Traceback (most recent call last):
File "C:/Users/rillig/git/python-playground/caesar.py", line 105, in <module>
print('Decrypted tekst: ' + decrypt(arguments, key))
File "C:/Users/rillig/git/python-playground/caesar.py", line 52, in decrypt
newindex = (index - key) % len(characters)
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
Oops. But that's easy to fix.
Like in every Python review here, have a look at PEP 8, the Python style guide. It has lots of tips on how to structure the code and format it nicely. Yes, it's a long document, so read it in little steps, as you have time.
In your greeting string, the first line looks weird. When you add a backslash immediately after the opening """
, the first line break is ignored in the string:
print("""\
_____ _
| __ \ | |
| | | | ___ _ __ ___ _ __ _ _ _ __ | |_ ___ _ __
| | | |/ _ \ '_ \ / __| '__| | | | '_ \| __/ _ \ '__|
| |__| | __/ | | | (__| | | |_| | |_) | || __/ |
|_____/ \___|_| |_|\___|_| \__, | .__/ \__\___|_|
__/ | |
|___/|_| """)
Now your logo looks good in the source code also.
To quote from your code:
characters = list(string.printable)[:-5]
Be careful that the encrypted text does not end in a space. That would not be visible on the screen. Imagine this small dialog:
Q: How much do I owe you?
A: 150
Now if that is encrypted and the final 0 is missing, that would be bad.
Continuing with your code:
except ValueError:
print('Invalid character(s)!')
This error message is a bit unspecific. If your program is friendly, it tells me which of the many characters I typed is invalid, ideally with some context so that I can find it.
print('''
Dencrypter commands
------------------------------------------
help Show this page
encrypt {text} Encrypt some text
key Display your current decryption key
key {key} Set a decryption key
decrypt {text} Decrypt some text
exit Close application
''')
I reformatted this usage section to start all descriptions in the same column. That way, I can easily scan the first word of each description to see which of the verbs is most appropriate to what I want to do.
I also normalized the periods at the end, the upper/lower spelling of the first letter and replaced Displays
with Display
, to match the grammar of the other entries.
By the way, it's great that you use actual verbs as the commands. I see many other beginner programs that have numbered menu items: Press 1 to encrypt a text. Press 2 to enter a decryption key. And so on. Your variant is the way to go.
You should normalize tekst
to text
. :)
I really like the Use it like this
instructions. They are essential for having fun with the program. "Don't tell me what I did wrong, rather tell me how to do it correctly."
To make your program easily testable, it should do all of its work in a function called main
. See this question for further details.
Explore related questions
See similar questions with these tags.