#Stops the program going over the 25 (because 26 would be useless)
#character limit
MAX = 25
#Main menu and ensuring only the 3 options are chosen
def getMode( ) :
while True :
print ( 'Main Menu: Encrypt (e), Decrypt (d), Stop (s), Block Encrypt (be).' )
mode = input ( ) .lower ( )
if mode in 'encrypt e decrypt d block encrypt be' .split ( ) :
return mode
if mode in 'stop s' .split ( ) :
exit( )
else :
print ( 'Please enter only "encrypt", "e", "decrypt", "d", "stop", "s" or "block encrypt", "be"' )
def getMessage( ) :
print ( 'Enter your message:' )
return input ( )
#Creating the offset factor
def getKey( ) :
key = 0
while True :
print ( 'Enter the offset factor (1-%s)' % ( MAX) )
key = int ( input ( ) )
if ( key >= 1 and key <= MAX) :
return key
#Decryption with the offset factor
def getTranslatedMessage( mode, message, key) :
if mode[ 0 ] == 'd' :
#The key is inversed so that it simply takes away the offset factor instead
#of adding it
key = -key
translated = ''
if mode == 'be' :
message = message.replace ( " " , "" )
#The spaces are all removed for the block encryption
#Ensuring that only letters are attempted to be coded
for symbol in message:
if symbol .isalpha ( ) :
number = ord ( symbol )
number += key
#Ensuring the alphabet loops back over to "a" if it goes past "z"
if symbol .isupper ( ) :
if number > ord ( 'Z' ) :
number -= 26
elif number < ord ( 'A' ) :
number += 26
elif symbol .islower ( ) :
if number > ord ( 'z' ) :
number -= 26
elif number < ord ( 'a' ) :
number += 26
translated += chr ( number)
else :
translated += symbol
return translated
#Returns translated text
mode = getMode( )
message = getMessage( )
key = getKey( )
#Retrieving the mode, message and key
print ( 'The translated message is:' )
print ( getTranslatedMessage( mode, message, key) )
#Tells the user what the message is
ICAgICNTdG9wcyB0aGUgcHJvZ3JhbSBnb2luZyBvdmVyIHRoZSAyNSAoYmVjYXVzZSAyNiB3b3VsZCBiZSB1c2VsZXNzKQojY2hhcmFjdGVyIGxpbWl0Ck1BWCA9IDI1CgojTWFpbiBtZW51IGFuZCBlbnN1cmluZyBvbmx5IHRoZSAzIG9wdGlvbnMgYXJlIGNob3NlbgpkZWYgZ2V0TW9kZSgpOgogICAgd2hpbGUgVHJ1ZToKICAgICAgICBwcmludCgnTWFpbiBNZW51OiBFbmNyeXB0IChlKSwgRGVjcnlwdCAoZCksIFN0b3AgKHMpLCBCbG9jayBFbmNyeXB0IChiZSkuJykKICAgICAgICBtb2RlID0gaW5wdXQoKS5sb3dlcigpCiAgICAgICAgaWYgbW9kZSBpbiAnZW5jcnlwdCBlIGRlY3J5cHQgZCBibG9jayBlbmNyeXB0IGJlJy5zcGxpdCgpOgogICAgICAgICAgICByZXR1cm4gbW9kZQogICAgICAgIGlmIG1vZGUgaW4gJ3N0b3Agcycuc3BsaXQoKToKICAgICAgICAgICAgZXhpdCgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQoJ1BsZWFzZSBlbnRlciBvbmx5ICJlbmNyeXB0IiwgImUiLCAiZGVjcnlwdCIsICJkIiwgInN0b3AiLCAicyIgb3IgImJsb2NrIGVuY3J5cHQiLCAiYmUiJykKCmRlZiBnZXRNZXNzYWdlKCk6CiAgICBwcmludCgnRW50ZXIgeW91ciBtZXNzYWdlOicpCiAgICByZXR1cm4gaW5wdXQoKQoKI0NyZWF0aW5nIHRoZSBvZmZzZXQgZmFjdG9yIApkZWYgZ2V0S2V5KCk6CiAgICBrZXkgPSAwCiAgICB3aGlsZSBUcnVlOgogICAgICAgIHByaW50KCdFbnRlciB0aGUgb2Zmc2V0IGZhY3RvciAoMS0lcyknICUgKE1BWCkpCiAgICAgICAga2V5ID0gaW50KGlucHV0KCkpCiAgICAgICAgaWYgKGtleSA+PSAxIGFuZCBrZXkgPD0gTUFYKToKICAgICAgICAgICAgcmV0dXJuIGtleQoKI0RlY3J5cHRpb24gd2l0aCB0aGUgb2Zmc2V0IGZhY3RvciAgICAgICAKZGVmIGdldFRyYW5zbGF0ZWRNZXNzYWdlKG1vZGUsIG1lc3NhZ2UsIGtleSk6CiAgICBpZiBtb2RlWzBdID09ICdkJzoKI1RoZSBrZXkgaXMgaW52ZXJzZWQgc28gdGhhdCBpdCBzaW1wbHkgdGFrZXMgYXdheSB0aGUgb2Zmc2V0IGZhY3RvciBpbnN0ZWFkCiNvZiBhZGRpbmcgaXQgICAgICAgIAogICAgICAgIGtleSA9IC1rZXkKICAgIHRyYW5zbGF0ZWQgPSAnJwoKICAgIGlmIG1vZGUgPT0gJ2JlJzoKICAgICAgICBtZXNzYWdlID0gbWVzc2FnZS5yZXBsYWNlKCIgIiwiIikKCiAgICAgICAgI1RoZSBzcGFjZXMgYXJlIGFsbCByZW1vdmVkIGZvciB0aGUgYmxvY2sgZW5jcnlwdGlvbgoKI0Vuc3VyaW5nIHRoYXQgb25seSBsZXR0ZXJzIGFyZSBhdHRlbXB0ZWQgdG8gYmUgY29kZWQKICAgIGZvciBzeW1ib2wgaW4gbWVzc2FnZToKICAgICAgICBpZiBzeW1ib2wuaXNhbHBoYSgpOgogICAgICAgICAgICBudW1iZXIgPSBvcmQoc3ltYm9sKQogICAgICAgICAgICBudW1iZXIgKz0ga2V5CiNFbnN1cmluZyB0aGUgYWxwaGFiZXQgbG9vcHMgYmFjayBvdmVyIHRvICJhIiBpZiBpdCBnb2VzIHBhc3QgInoiCiAgICAgICAgICAgIGlmIHN5bWJvbC5pc3VwcGVyKCk6CiAgICAgICAgICAgICAgICBpZiBudW1iZXIgPiBvcmQoJ1onKToKICAgICAgICAgICAgICAgICAgICBudW1iZXIgLT0gMjYKICAgICAgICAgICAgICAgIGVsaWYgbnVtYmVyIDwgb3JkKCdBJyk6CiAgICAgICAgICAgICAgICAgICAgbnVtYmVyICs9IDI2CiAgICAgICAgICAgIGVsaWYgc3ltYm9sLmlzbG93ZXIoKToKICAgICAgICAgICAgICAgIGlmIG51bWJlciA+IG9yZCgneicpOgogICAgICAgICAgICAgICAgICAgIG51bWJlciAtPSAyNgogICAgICAgICAgICAgICAgZWxpZiBudW1iZXIgPCBvcmQoJ2EnKToKICAgICAgICAgICAgICAgICAgICBudW1iZXIgKz0gMjYKCiAgICAgICAgICAgIHRyYW5zbGF0ZWQgKz0gY2hyKG51bWJlcikKICAgICAgICBlbHNlOgogICAgICAgICAgICB0cmFuc2xhdGVkICs9IHN5bWJvbAogICAgcmV0dXJuIHRyYW5zbGF0ZWQKI1JldHVybnMgdHJhbnNsYXRlZCB0ZXh0Cgptb2RlID0gZ2V0TW9kZSgpCm1lc3NhZ2UgPSBnZXRNZXNzYWdlKCkKa2V5ID0gZ2V0S2V5KCkKI1JldHJpZXZpbmcgdGhlIG1vZGUsIG1lc3NhZ2UgYW5kIGtleQoKcHJpbnQoJ1RoZSB0cmFuc2xhdGVkIG1lc3NhZ2UgaXM6JykKcHJpbnQoZ2V0VHJhbnNsYXRlZE1lc3NhZ2UobW9kZSwgbWVzc2FnZSwga2V5KSkKI1RlbGxzIHRoZSB1c2VyIHdoYXQgdGhlIG1lc3NhZ2UgaXM=