This is my first question posted to stackoverflow, any and all help/critique/assistance is appreciated...I need all the help I can get haha.
I am very new to programming.
The aim is to create a Caesar cipher that encrypts and decrypts user string input to an ord, adds the user input offset_value
, and then changes it back to a char.
I am using ASCII characters. The issue is that I need to isolate the encryption and decryption to ASCII 32 ('a') - ASCII 126 ('~'). I'm not sure how to create a function that circles back through the 94 characters.
So, for example, if the char is 'Z' which is ASCII ord 94, if we add the user input offset_value
, which could be 90 that would make the ord 184. Which is outside the range.
This leads into the real problem, the brute force encryption. It works...sort of. It needs to display every possible result with the offset_value
changing between 1 and 94. For example, what happens if we decrypt each letter with an offset_value
of x (x being any number from 1-94).
Instead it just keeps going up and up.
Does any of this make sense?
My code is below. I know I haven't created any functions yet, but I will.
Thanks in advance guys.
choice = 0
list1 = [1, 2, 3, 4]
list2 = list(range(1, 95))
new_ord = 0
index = 1
encryption = ''
decryption = ''
offset_value = 1
#while loop allows for multiple use, option 4 ends loop
while choice != 4:
print('*** Menu ***')
print('\r')
print('1. Encrypt string')
print('2. Decrypt string')
print('3. Brute force decryption')
print('4. Quit')
print('\r')
choice = int(input('What would you like to do [1,2,3,4]? '))
#invalid user input loop, valid entry ends loop
while choice not in list1:
print('\r')
print('Invalid choice, please enter either 1, 2, 3 or 4.')
print('\r')
choice = int(input('What would you like to do [1,2,3,4]? '))
#user chooses 'encrypt string', stores data
if choice == 1:
print('\r')
string_to_encrypt = str(input('Please enter string to encrypt: '))
offset_value = int(input('Please enter offset value (1 to 94): '))
#invalid user input loop, valid entry ends loop
while offset_value not in list2:
offset_value = int(input('Please enter offset value (1 to 94): '))
#encryption loop for length of string_to_encrypt
for letter in string_to_encrypt:
encryption = encryption + chr((ord(letter) + offset_value))
#prints encrypted string
print('\r')
print('Encrypted string:')
print(encryption)
print('\r')
#clears ecryption data
encryption = ''
#user chooses 'decrypt string', stores data
elif choice == 2:
print('\r')
string_to_decrypt = str(input('Please enter string to decrypt: '))
offset_value = int(input('Please enter offset value (1 to 94): '))
#invalid user input loop, valid entry ends loop
while offset_value not in list2:
offset_value = int(input('Please enter offset value (1 to 94): '))
#decryption loop for length of string_to_decrypt
for letter in string_to_decrypt:
decryption = decryption + chr((ord(letter) - offset_value))
#prints decrypted string
print('\r')
print('Decrypted string:')
print(decryption)
print('\r')
#clears decryption data
decryption = ''
#user chooses 'Brute Force Decryption
elif choice == 3:
string_to_decrypt = str(input('Please enter string to decrypt: '))
for number in range(94):
for letter in string_to_decrypt:
decryption = decryption + chr((ord(letter) - offset_value))
print('Offset: ', index, '= Decrypted String: ', decryption)
offset_value = offset_value + 1
index = index + 1
decryption = ''
#user chooses 'quit'
print('Goodbye.')
Rather than rewrite your program for you, I'm going to describe how to tackle a problem like this, which is mostly involves doing a little math.
The essence of your question boils down to how to offset a given range of integer values a given amount and wrapping the results so they're all still within the original range of values.
This can be done mathematically for each value in the range by subtracting the minimum value in the range, adding the offset to that, calculating the sum modulo the difference between the high and low values of the range (+1), and then finally adding the minimum value back to compensate for initially subtracting it. The crucial part is the modulo %
operation to constrain the sum.
The code in the offset_range()
function below shows how to do all that inside a list comprehension which is a shorthand way to create lists in Python.
That and the print_range()
function also serve to illustrate how functions get defined in Python.
def print_range(name, range_):
""" Pretty-print given range of character ordinals. """
ints = ', '.join('{:3d}'.format(val) for val in range_)
chrs = ', '.join('{:>}'.format(repr(chr(val))) for val in range_)
print('{}: [{}]'.format(name, ints))
print('{} [{}]'.format(len(name)*' ', chrs))
def offset_range(offset_value, range_):
""" Add offset value to integers in given range and wrap result. """
min_val, max_val = range_[0], range_[-1] # Get upper and lower limits.
diff_plus_1 = (max_val - min_val) + 1 # Their difference + 1 for computation.
# Use a list comprehension to create new list.
offset_range = [(((val - min_val) + offset_value) % diff_plus_1) + min_val
for val in range_]
return offset_range
ascii_range = list(range(ord('a'), ord('~')+1))
print_range('ascii_range', ascii_range)
print()
offset_range = offset_range(1, ascii_range)
print_range('offset_range', offset_range)
Output:
ascii_range: [ 97, 98, 99, 100, 101, 102, 103, 104, 105, ... 122, 123, 124, 125, 126]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', ... 'z', '{', '|', '}', '~']
offset_range: [ 98, 99, 100, 101, 102, 103, 104, 105, ... 122, 123, 124, 125, 126, 97]
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', ... 'z', '{', '|', '}', '~', 'a']