This program essentially encodes and decodes a message and code respectively. I only did the decoding part so far. However I keep getting an EOF error even though I made sure to end parentheses, checked my syntax and kept tampering with it. Unfortunately no luck. Anyone know why this error keeps popping up? I would greatly appreciate it. Also I copied both files that i'm using.
from LetterCodeLogic import LCL
def main():
print("Welcome to the LetterCode program")
choice = getChoice()
while choice !=0:
if choice == 1:
#Encode logic...
print()
elif choice == 2:
#Decode logic...
msg = input("Enter your numbers to decode (separate with commas): ")
#send msg to Decode function in LCL class (LetterCodeLogic.py file)
result = LCL.Decode(msg)
print("Your decoded message is: \n" + result)
else:
print("Unknown process...")
print()
choice = getChoice()
print("Thanks for using the Letter Code program")
def getChoice():
c = int(input("Choice? (1=Encode, 2=Decode, 0=Quit): "))
return c
if __name__ == "__main__":
main()
class LCL:
"""Encode/Decode Functions"""
#staticmethod
def Decode(msg):
#separate numbers from msg string (e.g., "1,2,3")
nums = msg.split(",") #produces list of separate items
result = ""
for x in nums:
try:
n = int(x.strip()) #remove leading/trailing spaces...
if n == 0:
c = " "
elif n < 0 or n > 26:
c = "?"
else:
#ASCII scheme has A=65, B=66, etc.
c = chr(n+64)
except ValueError:
c = "?"
result += c #same as: result = result + c
return result
#staticmethod
def Encode(msg):
the "#staticmethod" and "def Encode()" function was empty and that was the end of line parsing error. When I was coding this and ran it, it ran with no problems. So I removed it for the time being.
I am trying to write a vigenere cipher code. My psuedo for this is :
- find the index for each letter in plaintext
- find the index for each letter in the key message
- add together the indexes
- new letters will be at the position of the sum of the indexes
I believe I got my code correctly organized but I'm not sure if I'm missing something because I'm getting a type error.
# global constants:
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
ALPHABET_SIZE = len(ALPHABET)
# main function definition:
def main():
# User interface:
print("Welcome to the Vigenere Cipher!")
keep_running = True
while(keep_running):
print("Enter 1 to encrypt a message")
print("Enter 2 to decrypt a message")
print("Enter 0 to exit")
print()
user_choice = int(input("What would you like to do? " ))
if user_choice == 0:
keep_running = False
if user_choice == 1:
plaintext = input("Enter a plaintext message to encrypt: ")
key = str(input("Enter a message to use as the key: "))
ciphertext = enc(key, plaintext)
print("Resulting cipertext:", ciphertext)
print()
if user_choice == 2:
ciphertext = str(input("Enter a ciphertext message to decrypt: "))
key = str(input("Enter a message to use as the key: "))
plaintext = dec(key, ciphertext)
print("Resulting plaintext:", plaintext)
print()
def enc(key, plaintext):
ciphertext = []
for cipher_char in plaintext:
char_pos = ALPHABET.index(cipher_char)
for key_char in key:
message_pos = ALPHABET.index(key_char)
new_pos = (char_pos + key_char)
enc_char = ALPHABET(new_pos)
plaintext += enc_char
return plaintext
# call to main:
main()
The error is at this line
new_pos = (char_pos + key_char)
char_pos is a position and is of type int. key_char is a character and is of type string. You can't add one to the other.
Also in these lines directly above:
for cipher_char in plaintext:
char_pos = ALPHABET.index(cipher_char)
for key_char in key:
message_pos = ALPHABET.index(key_char)
Each of the for loops set the variables (char_pos and message_pos respectively) over and over again. So only the positions of the last character in each string (plaintext and key respectively) in the alphabet are taken into account. So you need to rethink the logic somewhat.
Finally I suggest you include upper case characters in ALPHABET. I got a value error the first time I tried it because I tried upper case input.
I am building a text-based encryption and decryption game. There are different levels, and each level uses a different cipher for encrypting a text. I am trying to figure out the best practice for the series of questions and prompts (the narrative) I give the user to determine if he wants to practice, do the test, encrypt, or decrypt. 90% of the narrative is the same for each level, so I don't want to repeat myself with identical code. What is the best way to do this?
My first thought was to define a function that contained the general script, and to call the specific functions as parameters. (This is what I have attempted to do below). But I seem to run into a scope problem. When I call the caesar() function as one of the arguments in the script() function, I need to enter the text to be encrypted, but this text isn't provided by the user until the script() function has already started running.
Should I be using a class to define the narrative portion of the program, and then inherit to more specific types?
Or should I just repeat the narrative code at the different levels?
Here is the narrative script():
def script(encrypt, decrypt):
"""Asks user if they want to practice (encode or decode) or take the
test, and calls the corresponding function."""
encrypt = encrypt
decrypt = decrypt
while True:
print('Type Q to quit. Type M to return to the main menu.')
prac_test = input('would you like to practice or take the test? P/T')
if prac_test.lower() == 'p':
choice = input('Would you like to encrypt or decrypt? E/D ')
if choice.lower() == 'e':
text = input('Enter the text you would like to encode: ')
encrypt
elif choice.lower() == 'd':
text = input('Enter the text you would like to decode: ')
key = int(input('Enter the key: '))
decrypt
else:
print('You must enter either "E" or "D" to encode or decode a
text. ')
elif prac_test.lower() == 't':
text = random.choice(text_list)
encrypted_text = encrypt
print(encrypted_text[0])
answer = input('s/nCan you decode this string? ')
if answer.lower() == ran_str.lower():
print('Congrats! You solved level 1!\n')
pass
elif answer != ran_str:
print("Sorry, that's not correct. Why don't you practice some
more?\n")
script(encrypt, decrypt)
elif prac_test.lower() == 'q':
exit()
elif prac_test.lower() == 'm':
break
else:
print('Please enter a valid choice.')
Here is one of the levels using a caesar cipher:
def caesar(mode, text, key=None):
"""
...
The dictionaries that convert between letters and numbers are stored in the .helper file, imported above.
"""
mode = mode
if mode == 'encrypt':
key = random.randint(1, 25)
elif mode == 'decrypt':
key = key
str_key = str(key)
text = text.lower()
# converts each letter of the text to a number
num_list = [alph_to_num[s] if s in alph else s for s in text]
if mode == 'encrypt':
# adds key-value to each number
new_list = [num_to_alph[(n + key) % 26] if n in num else n for n in
num_list]
elif mode == 'decrypt':
# subtracts key-value from each number
new_list = [num_to_alph[(n - key) % 26] if n in num else n for n in
num_list]
new_str = ''
for i in new_list:
new_str += i
return new_str, str_key
And here is who I would try to use them together:
script(caesar('encrypt' text), caesar('decrypt', text, key))
Please instruct me on the best way to organize this reusable narrative code.
You probably want to use multiple functions:
One, that we will call main(), to display the menu and interact with the user
A class Caesar, that expose two functions: encrypt(text, key) and decrypt(text, key)
A simple program could then look like
def main():
print("Welcome to the game")
action = input("Would you like to encrypt or decrypt a text [e/d]">).lower()
text = input("What is the text you want to test on ? >")
key = input("What's your key")
# optionnaly, ask for what kind of cipher they want to use, then use a dict to chose the right class
cipher = Caesar()
if action == "e":
output = cipher.encrypt(text, key=key)
else:
output = cipher.decrypt(text, key=key)
print(output)
print("Thanks for playing!")
I am needing a bit of help on my encryption program. Instead of having the program just move the letters by two (c would become a or r would become p) I'd like to be able to have it reference 2 lists, the first one going from a-z normally and the other with letters in different order to act as the encrypt/decrypt side. Hopefully that makes sense. Here's what i have so far.
result = ''
choice = ''
message = ''
while choice != 0:
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if choice == '1':
message = input('\nEnter message for encryption: ')
for i in range(0, len(message)):
result = result + chr(ord(message[i]) - 2)
print(result + '\n\n')
result = ''
if choice == '2':
message = input('\nEnter message to decrypt: ')
for i in range(0, len(message)):
result = result + chr(ord(message[i]) + 2)
print(result + '\n\n')
result = ''
elif choice != '0':
print('You have entered an invalid input, please try again. \n\n')
This works fine and dandy but i'd like to have the lists. Lets say list 1 is A,B,C,D,E and list 2 would be W,N,U,D,P. just for ease of use purposes.
Here is a solution, for small letters only. It can easily be modified to handle also capital letters, by adding them to the text strings.
As can be seen, the space character is at the same position in both lists. This is not necessary, as any character can be translated to any other. However if the decrypted or encrypted is not containing unique characters only, the program will break down.
decrypted = b"abcdefghijklmnopqrstuvwxyz "
encrypted = b"qwertyuiopasdfghjklzxcvbnm "
encrypt_table = bytes.maketrans(decrypted, encrypted)
decrypt_table = bytes.maketrans(encrypted, decrypted)
result = ''
choice = ''
message = ''
while choice != '0':
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if choice == '1':
message = input('\nEnter message for encryption: ')
result = message.translate(encrypt_table)
print(result + '\n\n')
elif choice == '2':
message = input('\nEnter message to decrypt: ')
result = message.translate(decrypt_table)
print(result + '\n\n')
elif choice != '0':
print('You have entered an invalid input, please try again. \n\n')
Ok, so a few things here...
First I'll give you exactly what you were looking for and explain what I used and some of the changes that needed to be made to your original code. Then I'll explain some inherent issues what what you're trying to do and suggest some areas to read up on/some ways you might want to improve what you've got.
Here's the code you're looking for (while retaining the same flow as what you submitted put above):
import random
result = ''
choice = ''
message = ''
characters_in_order = [chr(x) for x in range(32,127)]
while choice != 0:
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if str(choice) == '1':
message = input('\nEnter message for encryption: ')
r_seed = input('Enter an integer to use as a seed: ')
random.seed(r_seed)
shuffled_list = [chr(x) for x in range(32,127)]
random.shuffle(shuffled_list)
for i in range(0, len(message)):
result += shuffled_list[characters_in_order.index(message[i])]
print(result + '\n\n')
result = ''
elif str(choice) == '2':
message = input('\nEnter message to decrypt: ')
r_seed = input('Enter an integer to use as a seed (should be the same one used to encrypt): ')
random.seed(r_seed)
shuffled_list = [chr(x) for x in range(32,127)]
random.shuffle(shuffled_list)
for i in range(0, len(message)):
result += characters_in_order[shuffled_list.index(message[i])]
print(result + '\n\n')
result = ''
elif str(choice) != '0':
print('You have entered an invalid input, please try again. \n\n')
You'll notice that I set a global 'characters in order' list, which is just every ASCII character (32-126) in order. I also imported the 'random' module and used this to shuffle the characters in order according to a seed that the user inputs. As long as this seed is the same on the encryption and decryption end, it will produce the same shuffled list and it should work to encrypt or decipher the same string. Also notice the str() around your input choices. Without that, the user had to input '1', rather than 1 to submit a choice without an error.
All of that said...
Notice that the way the new function works is by looking at a character's index in one list and pulling out the character at that index in another. The method you were using, of incrementing or decrementing a character's ASCII code is basic (though not much more basic than this), but it also has a pretty critical flaw, which is that characters on one end or another of the ASCII set wouldn't return ASCII characters. If you were encrypting it at a bit-level, which would be preferred, this wouldn't matter/would be irrelevant, but here you're not going to get the kind of string back that you want if you were to, for example, enter a [space] (ASCII 32) into your plaintext to be encrypted.
If you're interested, you might want to read up on symmetric key encryption/DES for some ideas on how encryption is really done, though props on the start/interest and this can certainly be a fun way to create some sort of cryptogram puzzle or something along those lines. I won't pretend to be any kind of expert, but I can at least point you in the write direction. (https://en.wikipedia.org/wiki/Data_Encryption_Standard https://en.wikipedia.org/wiki/Symmetric-key_algorithm)
Consider having your code read in a .txt file and print out to a .txt file, rather than using user input for the message.
Again, I'm not an expert by any means and there are definitely some fun uses of the kind of program you're aiming for, just trying to point you in the right direction if this is something that you're interested in. Hope all of that is helpful!
Here is my solution. It uses a randomizer to encrypt the file by assigning a ASCII value to the plain text and randomly shifts it around.
from random import randint
import sys
def menu():
input1=int(input(""" please select what you want to do:
1.Encrypt
2.Decrypt
3.Extended Encryption
4.exit
"""))#menu to choose what you want to do
if input1==1:
encrypt() #takes you to the encrypt function
elif input1==2:
decrypt()#takes you to the decrypt function
elif input1==3:
enxtended()#takes you to the extended encryption function
elif input1==4:
sys.exit #exits the program
else:
print("invalid entry try again")
menu()
def encrypt():
file_name=str(input("please enter the name of the file that you want to open\n"))
try:
text_file=open(file_name + ".txt","r")#puts the text file into read
text_file=text_file.read()#reads the text file
print(text_file)#prints the strings in the document
except:
print("error try again")
encrypt()
random(text_file)
def random(text_file):
list1=("")#creates blank string
for x in range (0,8):
num=(randint(33,126))#generates a random number between33 and 126
ascii1=chr(num) #converts it into an ascii character
list1=list1+ascii1#adds the ascii character to the blank string list1
print (f"your 8 key code is {list1}") #prints 8 character code
offset(list1,text_file)
def offset(list1,text_file):
total=0
for x in range (8,):
total=total+ord(list1[x]) #turns each character into an ascii value
total=total/8 #divides it by
total=round(total,0)#rounds it to 0 decimel places
print(total)
total=total-32#minuses 32 from total
print(f"your offset factor is {total}")
encrypting(total,text_file)
def encrypting(total,text_file):
length=len(text_file)
string1=("")
for x in range (length,):
numascii=ord(text_file[x])#turns the characters into its ascii value
numascii=int(numascii)#makes sure they are integers
if numascii==32:
letter=chr(32)#converts spaces back into spaces
string1=string1+letter#adds space to thestring
else:
numascii1=numascii+total#adds the character value to the offset factor
numascii1=int(numascii1)#makes sure it is an integer
if numascii1>126:# if the ascii value is great then 126
numascii1=numascii1-94#minus 94 from it
letter=chr(numascii1)#turn it into a character
string1=string1+letter#add it to the string
else:
letter=chr(numascii1)#turn the ascii value into a character
string1=string1+letter#add it to the string
print(f"your encrypted file is {string1}")
savefile(string1)
menu()
I have written separate programs for encryption and decryption. Both of these use file manipulation techniques. Use the username 'eggs' and password 'chicks' so that not anyone can see my secret code. I have used hashlib for more security. Just change the User 'Soumajit' to your respective Username to make it work. The first one is encryption and the next one is for decryption.
#ENCRYPTION
from time import sleep
import subprocess
import hashlib
def copy2clip(txt):
cmd='echo '+txt.strip()+'|clip'
return subprocess.check_call(cmd, shell=True)
def en():
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&* ()`-+=1234567890"
encrypt = ""
decrypt = ""
print
print "Type y for yes and anything else for no"
start = raw_input("Do you want to import file from desktop? ")
if start == "y":
Open = raw_input("Enter the .txt file you want to open in desktop: ")
a = open("C://Users//Soumajit//Desktop//" + Open + ".txt", "r")
print
x = (a.read())
copy2clip(x)
a.close()
print "Right click and select paste below to encrypt"
print
message = raw_input()
for i in message:
x = alphabet.find(i)
new = (x - 5) % 74
encrypt += alphabet[new]
e2 = encrypt[::-1]
else:
print "Type your message below"
message = raw_input("")
for i in message:
x = alphabet.find(i)
new = (x - 5) % 74
encrypt += alphabet[new]
e2 = encrypt[::-1]
print
a = raw_input("By what name do you want to save it?: ")
file = open(a + ".txt", 'wb')
file.write(e2)
file.close()
copy = raw_input("Do you want to copy your file? ")
if copy == 'y':
copy2clip(e2)
print 'Your encrypted file has been copied to the clipboard'
else:
print "Your encrypted file has been saved with the name " + str(a) + " in desktop"
print "To decrypt it, use my other program"
sleep(3)
u = 'e415bf03b4d860dccba57cea46371f831d772ba1deca47f28fa7d1f7'
p = 'c35f7f79dc34a678beb2b4106c84c9963561e7c64bc170e50c429b9a'
ur = raw_input('Enter your username: ')
ur1 = hashlib.sha224(ur).hexdigest()
pr = raw_input('Enter your password: ')
pr1 = hashlib.sha224(pr).hexdigest()
if ur1 == u and pr1 == p:
print 'Access granted'
sleep(1)
en()
else:
print "Incorrect username or password"
sleep(1)
#DECRYPTION
from time import sleep
import subprocess
import hashlib
def copy2clip(txt):
cmd='echo '+txt.strip()+'|clip'
return subprocess.check_call(cmd, shell=True)
def de():
print "Type y for yes and anything else for no"
start = raw_input("Do you want to import file from desktop? ")
if start == "y":
Open = raw_input("Enter the .txt file you want to open from folder: ")
a = open("C://Users//Soumajit//Desktop//" + Open + ".txt", "r")
x = (a.read())
#print x
copy2clip(x)
print "Right click and select paste below to decrypt"
print
message = raw_input()
a.close()
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&*()`-+=1234567890"
decrypt = ''
for i in message:
x = alphabet.find(i)
new = (x + 5) % 74
decrypt += alphabet[new]
d2 = decrypt[::-1]
d3 = d2.replace("`", " ")
final = d3.replace("2", " ")
print
print final
else:
print "Type or paste your encrypted text below"
print
message = raw_input()
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&*()`-+=1234567890"
decrypt = ''
for i in message:
x = alphabet.find(i)
new = (x + 5) % 74
decrypt += alphabet[new]
d2 = decrypt[::-1]
d3 = d2.replace("`", " ")
final = d3.replace("2", " ")
print
print final
u = 'e415bf03b4d860dccba57cea46371f831d772ba1deca47f28fa7d1f7'
p = 'c35f7f79dc34a678beb2b4106c84c9963561e7c64bc170e50c429b9a'
ur = raw_input('Enter your username: ')
ur1 = hashlib.sha224(ur).hexdigest()
pr = raw_input('Enter your password: ')
pr1 = hashlib.sha224(pr).hexdigest()
if ur1 == u and pr1 == p:
print 'Access granted'
sleep(1)
de()
print
end = raw_input('press q to quit: ')
while end != 'q':
print 'You did not type q'
end = raw_input('press q to quit: ')
if end == 'q':
quit()
else:
print 'Incorrect username or password'
sleep(1)
quit()
Im trying to incorporate my encryption program into a chat program. But i cant pass a MutableString with Socket. So how would I properly covert my MutableString into a proper string?
import sys
from UserString import MutableString
def GetMode():
while True:
print '\n(E)ncrypt Or (D)ecrypt?'
Mode = raw_input().lower()
if Mode in 'e d encrypt decrypt'.split():
return Mode
else:
print '\nEnter Proper Choice!'
def GetInput():
while True:
print '\n(T)ype Message Or (L)oad File?'
Input = raw_input().lower()
if Input in 't type'.split():
Input = raw_input('>')
return Input
elif Input in 'l load'.split():
MsgLoc = raw_input()
MsgLoc = open(MsgLoc, 'r')
try:
Input = MsgLoc.read()
MsgLoc.close()
return Input
except:
print '\nCould Not Open' , MsgLoc
else:
print '\nEnter Proper Choice!'
def GetKey():
while True:
Key = 0
print '\nPlease Enter A 20 Digit Number...\n** Do NOT use zeros!!!! EX-NAY ERO-ZAY! **'
try:
Key = int(input())
Key = str(Key)
if (len(Key) == 20):
return Key
else:
print('\nPlease Enter A Valid Number!')
except:
print('\nPlease Enter A Valid Number!')
def Translate(Mode, Input, Key):
if Mode[0] == 'e':
print('\nEncrypting....')
Encrypt(Input, Key)
else:
print('\nDecrypting....')
Decrypt(Input, Key)
def Encrypt(Input, Key):
Msg = MutableString()
NonMutMsg = Input
Msg += NonMutMsg
MsgLen = len(Msg)
CypherKey = Key
a = 0
b = 19
#Loop For Proccessing Key
for z in range(10):
KeySkip = int(CypherKey[a])
KeyIncrement = int(CypherKey[b])
c = MsgLen/KeySkip
d = -1
#Loop To Skip Then Increment
for y in range(c):
d = d+KeySkip
LtrNum = ord(NonMutMsg[d])
LtrNum = LtrNum + KeyIncrement
Msg[d] = chr(LtrNum)
First of all, as the MutableString documentation states:
It should be noted that these classes are highly inefficient compared to real string or Unicode objects; this is especially the case for MutableString.
and most importantly:
The main intention of this class is to serve as an educational example for inheritance
In other words, don't use this class in real world code.
To get the data out, use the data parameter:
pythonstring = mutablestring.data