# (Final)Simple Decryptor/Encryptor

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:

• 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
------------------------------------------
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}')


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.

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.

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
------------------------------------------
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.