trouble with the vigenere cipher - python

print ("")
print ("Welcome to Vigenere cipher!")
print ("")
print ("This program will encrypt then offer you a decryption of your message.")
print ("")
print ("Start this off with inputting your message you would like to encrypt.")
m = input("")
print ("")
print ("Now enter your keyword you would like to use. (it must be (" +str(len(m)),"or less letters.))")
k = input("")
if len(k) > len(m):
print ("")
print ("sorry this is an invaild keyword")
print ("Please re-enter your keyword.")
k = input("")
else:
print ("Your keyword is great. Lets keep going")
print ("")
print ("Is this correct?")
print ("")
print("-------\n"
"Message: ",m,"\n"
"Key: ",k,
"\n-------")
print ("")
print ("yes or no")
correct = input ("")
if 'yes'.startswith(correct.lower()):
print("Great! Lets keep going.")
else:
print ("You previously put: " +str(m), " as your message.")
print ("Please re-enter the keyword you wish to use. (it must be (" +str(len(m)),"or less letters.))")
k = input("")
encrypted = ("")
print ("")
for a in m:
print ("The message letters are")
encrypt2 = ord(a)
for b in k:
print ("The keyword letters are")
encrypt = ord(b)
encrypt3 = (encrypt) + (encrypt2)
encrpyted = chr(encrypt3)
print (chr(encrypt3))
I need it to encrypt with the keyword, any help?
p.s it needs to be basic like the code above.
it is for GCSE (UK)
if it needs to have some commands then can you please tell me what they do :) so i can explain it in the task :)

first, failures in your question:
all the code up for a in m: is unnecessary, all that is not part of your problem, your real problem is to encrypt a word using the vigenere cipher's algorithm, this can be replaced by two lines:
message = "ATTACKATDAWN"
key_adj = "LEMONLEMONLE"
or if you prefer
message = "ATTACKATDAWN"
key = "LEMON"
#key_adj and message equal length
key_adj = key + key*((len(message)/len(key))-1) + key[:len(message)%len(key)]
#key_adj is LEMONLEMONLE
Note: i rename the variables so that the people who help you, better understand,
as the input isn't a problem now, i can solve the problem
second, failures in your algorithm:
The most visible fault is using nested for, more isn't better, this complicates your solution, for this problem you need only one for
for a in m:
for b in k:
....
second failure, is the cipher equation .... for example, first letters:
letter_menssage = "A" -> ord("A") = 65
letter_key = "L" -> ord("L") = 76
+141 -> chr(141) = "ì"
with all this explanation , now I can show a solution:
#i use zip function, match letter message with letter key
# (A,L) (T,E) (T,M) (A,O) (C,N) (K,L) etc.
encrypt = ""
for letter_msg, letter_key in zip(message, key_adj):
code_letter_msg = ord(letter_msg)-ord('A')
code_letter_key = ord(letter_key)-ord('A')
encrypt += chr((code_letter_msg+code_letter_key) % 26 + ord('A'))
print (encrypt)
you get:
LXFOPVEFRNHR
explanation equation:
letter_menssage = "A" -> ord("A")-65 = 0
letter_key = "L" -> ord("L")-65 = 11
((0+11)%26 + 65)-> chr(76) = "L"
letter_menssage = "T" -> ord("A")-65 = 19
letter_key = "E" -> ord("E")-65 = 4
((19+4)%26 + 65)-> chr(88) = "X"

Related

This Python quiz is driving me crazy

I'm new to StackOverflow (1st time posting) and new to coding with python. Currently enrolled in a course through Udacity. I'm having a very hard time with a project we were given for this course and decided to come here to see if anyone could help.
The project is to create a quiz with 4 blanks that need to be answered correctly by the player. It's required to have the quiz print out with the correct answer, but I'm having a very hard time getting this to print out correctly.
My code is below. Would appreciate any help or advice I can get on this.
Thanks!
easy_quiz = "If you ever get stuck, check out the __1__ for common
problems students face when attempting this project. If you need
additional help, you can schedule a 1:1 appointment with one of our
__2__ to get you un-stuck. This project should be __3__. If at any time
it becomes not fun, take a step back, deep breath, and ask for __4__!.
\n\n"
easy_answers = ["forums", "mentors", "fun", "help"]
medium_quiz = "Game must have 3 or more levels and each level contains 4 or more __1__ to fill in. Immediately after running the program, user is prompted to select a difficulty level from easy / __2__ / hard. Once a level is selected, game displays a fill-in-the-blank and a prompt to fill in the first one. When player guesses __3__, new prompt shows with correct answer in the previous blank and a new prompt for the next blank. When player guesses __4__, they are prompted to try again. \n"
medium_answers = ["blanks", "medium", "correctly", "incorrectly"]
hard_quiz = "__1__ are used as __2__ to automate tasks which are likely to be repeated. Functions produce the appropriate output (typically with a __3__ statement) from the appropriate input (function parameters). Your code should take advantage of __4__ and variable names should reflect the values they store. \n"
hard_answers = ["Functions", "tools", "return", "variables"]
blanks = ["__1__", "__2__", "__3__", "__4__"]
difficulty = raw_input("\nChoose your difficuty level = easy, medium, or hard? ")
print ""
if difficulty == "easy":
quiz = easy_quiz
answers = easy_answers
print "You chose easy!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + easy_quiz
elif difficulty == "medium":
quiz = medium_quiz
answers = medium_answers
print "You chose medium!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + medium_quiz
elif difficulty == "hard":
quiz = hard_quiz
answers = hard_answers
print "You chose hard!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + hard_quiz
def word_in_pos(word, parts_of_speech):
for pos in parts_of_speech:
if pos in word:
return pos
return None
def play_game(quiz, parts_of_speech):
replaced = []
i = 0
quiz = quiz.split()
for word in quiz:
replacement = word_in_pos(word, parts_of_speech)
if replacement != None:
user_input = raw_input("Type an answer for: " + replacement + " " )
word = word.replace(replacement, user_input)
replaced.append(word)
guesses = 0
while user_input != answers[i]:
guesses = guesses + 1
print "Incorrect, try again \n" + " ".join(replaced)
user_input = raw_input("Type an answer for: " + replacement + " ")
if guesses == 4:
return "\nGame Over! Better luck next time. \n"
print "Correct \n" + " ".join(replaced)
i = i + 1
word = word.replace(replacement, user_input)
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
print play_game(quiz, blanks)
Here is a working version of your play_game() method:
def play_game(quiz, parts_of_speech):
replaced = []
i = 0
quiz = quiz.split()
for word in quiz:
replacement = word_in_pos(word, parts_of_speech)
if replacement is not None:
user_input = raw_input("Type an answer for: " + replacement + " " )
guesses = 0
while user_input != answers[i]:
guesses = guesses + 1
if guesses == 5:
return "\nGame Over! Better luck next time. \n"
print "Incorrect, try again \n" + " ".join(replaced) + " " + replacement
user_input = raw_input("Type an answer for: " + replacement + " ")
replaced.append(user_input)
print "Correct \n" + " ".join(replaced)
i = i + 1
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
The main change is to delay modifying the replaced list until the correct answer has been given. That simplifies a lot of the code, eliminating the need for the word variable.

My program runs but it doesn't output an Encrypted Message

The code I wrote is a Vignere Cipher encryption program that uses a keyword to encrypt a message. I wrote this code and when I finished it I ran it and it did all it was supposed to but output the encrypted message. See my code below, any help is gratefully received:
ans = False
print(""" *****Hello. Welcome to the Vignère Cipher Encryption Program*****
***This program uses a keyword that is repeated until it
matches the same lenght of the message and then adds its
numerical value to the numerical value of the message and
outputs the encrypted message in alpha.
Please press:
E to Encrypt
D to Decrypt
or double tap enter to quit.
""")
ans=input("What would you like to do now???")
if ans == "E":
plaintext = input("Please enter a message to be encrypted: ").upper()
keyword = input("Please enter a keyword to be used to encrypt a message (alpha only): ").upper()
ciphered = " "
for i in range (len(plaintext)):
char = plaintext[i]
alphakeywordvalue = ord(keyword[i%len(keyword)]) - ord("A")+1
if char.isupper():
if ans == "E" :
value = ord(char) + alphakeywordvalue
if value > ord("Z"):
value -= 26
print ("Your encrypted text is:", ciphered)
elif ans == "D":
plaintext = input("Please enter a message to be dencrypted: ").upper()
keyword = input("Please enter a keyword to be used to dencrypt a message (alpha only(make sure that it is the same keyword used to encrypt the message)): ").upper()
ciphered = " "
for i in range (len(plaintext)):
char = plaintext[i]
alphakeywordvalue = ord(keyword[i%len(keyword)]) - ord("A")+1
if char.isupper():
if ans == "D" :
value = ord(char) - alphakeywordvalue
if value <ord("A"):
value += 26
ciphered += chr(value)
print ("Your decrypted text is:", ciphered)
This is not a good style of writing code. Very shabby and hard to read. You should make methods for individual parts and create a separate main() like section to interact with the user, if required. Engine should be hidden, car body should be polished. Keep them separate. And yes, DO NOT REPEAT YOURSELF
Well, here's my re-written code. Important parts contain the comments. Errors are explained after it..
def encrypt(message, key, direction='E'):
# Look here. There are three arguments. Third one takes 'E' to encrypt
# and anything else to decrypt. You can modify to handle more cases
ciphered = "" # Initialize. You did it almost well
for i in range (len(message)):
char = message[i]
alphakeywordvalue = ord(key[i%len(key)]) - ord("A")+1 # Perfect. We took the key
if direction=='E': # To encrypt
value = ord(char) + alphakeywordvalue
else: # To decrypt
value = ord(char) - alphakeywordvalue
ciphered += chr(value) # chr is the inverse of ord. It gets the character back
# You missed this line
return ciphered
That's it. Now you can write the code to interact with user or other modules. Here's a sample test:-
message = "Hello World"
key = "abc"
print "ORIGINAL : "+message
encoded_message = encrypt(message, key, 'E')
print "ENCRYPTED : "+encoded_message
plain_message = encrypt(encoded_message, key, 'D')
print "DECRYPTED : "+plain_message
Here's the output:
Now you can edit this method to handle more cases like out of ascii range characters etc.
How could it print the encrypted message, the encryption routine never changes ciphered from an empty string.
if ans == "E":
plaintext = input("Please enter a message to be encrypted: ").upper()
keyword = input("Please enter a keyword to be used to encrypt a message (alpha only): ").upper()
1)-> ciphered = " "
for i in range (len(plaintext)):
char = plaintext[i]
alphakeywordvalue = ord(keyword[i%len(keyword)]) - ord("A")+1
2)-> if char.isupper():
3)-> if ans == "E" :
value = ord(char) + alphakeywordvalue
if value > ord("Z"):
value -= 26
4)-> print ("Your encrypted text is:", ciphered)
ciphered set to empty string, is never changed.
You always know char is upper, because you made all the plaintext upper()
You know ans == "E" because you tested it earlier
This print() is so far indented it tries to print every time through the loop

While-Loop Use in Python

When you come to the 2nd while loop while x == 2: it's still repeating the whole script even though x /= 1 (not if "n"is entered). Let say we enter "y" on the prompt "Is this correct?" shouldn't x become 3 which stops both the first and the 2nd loop?
This is probably obvious but I'm pretty new.
# -*- coding: utf-8 -*-
import time
x = 1
while x == 1:
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
while x == 2:
if correct == "y":
x = 3 # x = 3 skips all whiles, not working
time.sleep(1)
elif correct == "n":
time.sleep(1)
x = 1 # x = 1 --> 1st while still in action
else:
print "Invalid input \n\t Loading..."
x = 2 # x = 2 --> 2nd while takes over
print "Where do you live?"
time.sleep(0.5)
country = raw_input("Country: ")
time.sleep(0.5)
city = raw_input("City: ")
time.sleep(1)
print " \n Data: \n\t Name: %r \n \t Age: %r \n \t Country: %r \n \t
City: %r " % (name, age, country, city )
In the code you never change the value of your x to 2 so your inner loop while x==2: never runs and you loop infinitely. You need to change the value of x just inside the while x==1: loop for you to even enter the second loop.
The while structure is totally unnecessary, use functions instead and chain them
def ask():
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
return decide(name,age) #<-- Goes to decide
def decide(name,age):
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
if correct == "y":
return name,age #<-- process finishes
elif correct == "n":
return ask() #<-- goes back to asking
else:
print "Invalid input"
return decide(name,age) #<--Goes back to wait for a valid input
name, age = ask() #<--Starts the whole process
While I like my other answer better, if you want this code to work with just a slight modification, just bring the definition of correct to the inner loop and as Abdul Fatir say, kick in an x = 2. Anyhow using creating a state machine this way is not recommended.
x = 1
while x == 1:
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
x = 2 #<--Necessary
while x == 2:
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
if correct == "y":
x = 3 # x = 3 skips all whiles, not working
time.sleep(1)
elif correct == "n":
time.sleep(1)
x = 1 # x = 1 --> 1st while still in action
else:
print "Invalid input \n\t Loading..."
x = 2 # x = 2 --> 2nd while takes over
I like the solution involving chaining functions, but I also think that you could use some help with your input validation. I really nice tool for this is not in to validate it ahead of time. For instance
def ask():
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
return decide(name,age) #<-- Goes to decide
def decide(name,age):
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
while correct not in ["y", "n"]:
correct = raw_input("(y/n): ")
if correct == "y":
return (name,age) #<--process finishes
else
return ask() #<-- goes back to asking
Just to be clear, I ripped a large portion of that code from another answer, but I think that doing it that way is more efficient, and puts all acceptable answers in once place for easy viewing. It would even allow for more complex input validation, and potentially let you use a constant or config file to define available options.

duplicate word in hangman game

import random
words=["cat", "dog", "animal", "something", "whale", "crocodile", "lion", "summer", "boston", "seattle"]
the_word=random.choice(words)
#print(the_word)
a=len(the_word) #number of letter in the word
c=['_'for i in range(a)]#blanks seperated
blanks=" ".join(c)
print("This is a word with",a,"letter")
print("\t", blanks)
guess=0
while guess<3:
answer=input("Please enter a letter: ")
if answer in the_word:
the_index=the_word.index(answer)#find the index
c[the_index]=answer
blanks=" ".join(c)
print(blanks)
else:
guess=guess+1
print("There is no",answer,"in the word.")
I have two problems:
1st I can't reveal 2 words, summer for example, if a user input 'm' it will reveal only the first letter 'm'
2nd when the user input more than one word the program still consider right answer. For example: The user input "nm" for the word "something" the program still consider it right, and the word turn out like this "somethinmg"
You can check the length of answer via something like
if len(answer) != 1:
print "Please enter just one letter"
Or you can simply take only the first letter of what they enter
letter = answer[0]
See How to find all occurrences of an element in a list? on how to find multiple indexes that match.
Okay first of all to do the display I would take the word, split it up into letters and then create a list with the same length containing all '_'. This way you could display the _ _ _ _ etc by calling ' '.join(substitutelist)....
To get multiple letter responses:
each guess call
for letter in range(len(word)):
if word[letter]==guess.lower():
substitutelist[letter]=guess.lower()
Then every time a letter was called I would add it to a list titled something like "USED" and check each guess to make sure its not in zip(word, used) and if it is return a message error.
Here is an example hangman code I wrote to show the different functions...
import re, sys
from random import choice
def showmap(hangmanpic):
"""Will show the hangman pic after subtracting any
characters holding the place of a future body part"""
tempmap=''
x=str(range(7))
for i in hangmanpic:
if i in x:
tempmap+=' '
else:
tempmap+=i
return tempmap
def addbodypart(remaining, hangmanmap):
"""takes the hangman map and substitutes in a body
part when a wrong answer is chosen. Returns the new
hangmanmap"""
bodyparts={'6':'(_)',
'5':'|',
'3':'\\\\',
'2':'\\\\',
'4':'/',
'1':'/'
}
return re.sub(str(remaining), bodyparts[str(remaining)], hangmanmap)
def StartGame(hangmanmap, word):
"""Starts the game"""
dashword, wrong=[], []
remaining=6
for i in word:
dashword.append('_')
while remaining>0:
if '_' not in dashword:
remaining=0
continue
for i in range(5):
print ""
print "Guesses Left = %d" %(remaining)
print showmap(hangmanmap)
print ""
print "Used Letters: %s" %(', '.join(wrong))
print "Word: %s"%(' '.join(dashword))
guess=str(raw_input('Guess a letter:')).lower()
if guess in str(wrong)+str(dashword):
print ""
print "Sorry but you have already guessed that letter. Please guess again."
print ""
continue
if guess not in word:
hangmanmap=addbodypart(remaining, hangmanmap)
remaining-=1
wrong.append(guess)
else:
for i in range(0, len(word)):
if word[i]==guess:
dashword[i]=guess
if '_' not in dashword:
for i in range(5):
print ""
print "You WIN! Congrats"
print "The word was %s" %(word)
print showmap(hangmanmap)
print "Used Letters: %s" %(', '.join(wrong))
print "Word: %s"%(' '.join(dashword))
else:
for i in range(5):
print ""
print showmap(hangmanmap)
print "Word: %s" %(word)
print "Sorry but you've ran out of guesses! You Lose! The correct word was %s" %(word)
def main():
word=str(choice([line.strip() for line in open(sys.argv[1])])).lower()
hangmanmap=""" _________
|/ |
| 6
| 354
| 5
| 1 2
|
___|___"""
print "Welcome to AmazingReds Hangman Game!"
print "6 wrong answers and YOU LOSE! Good Luck."
StartGame(hangmanmap, word)
if __name__ == '__main__':
main()

Replacing words in Python?

I'm trying to replace the letters in key with the letters in alpha (and vice versa):
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
I am trying to change a string to become encoded (and the other way around), so say "Hello" would become "LTZZE". Any idea how to do this? This is my current code:
usrInput = 0
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
def menu():
print "SECRET DECODER MENU"
print ""
print "1) Quit"
print "2) Encode"
print "3) Decode"
usrInput = raw_input("What would you like to do?")
return usrInput
def encodeWord():
plain = plain.upper()
length = len(plain)
encode = plain.encode(alpha, key)
return encode
def decodeWord():
coded = coded.upper()
length = len(coded)
decode = coded.decode(key, alpha)
return decode
def main():
keepGoing = True
while keepGoing:
usrInput = menu()
if usrInput == "2":
plain = raw_input("Text you want to be encoded: ")
encodeWord()
print encode(plain)
elif usrInput == "3":
coded = raw_input("Code you need to be decyphered: ")
decodeWord()
print decode(coded)
elif usrInput == "1":
print "Thanks for doing super secret spy stuff with me. No one seems to want to anymore. Goodbye. ):"
keepGoing = False
else:
print "I don't know what to do! Ahhh!"
main()
Note this is a homework assignment for a computer science class. I created the assignment, and I'm aware it's on stack overflow. If you turn it in as your own work, I will know. You will earn a zero for the assignment and we will begin academic misconduct proceedings.
(If you're playing along at home, this is indeed a string manipulation assignment, and explicitly NOT to be considered a good cryptographic practice. We also are not allowing maketrans() for this assignment, because it's a string manipulation and function exercise for beginning programmers.)
If you're really desperate for help, come see me or one of the recitation leaders we're paying to help you.
Use str.maketrans and str.translate. If you use Python 2 this functions are in string (here (maketrans) and here (translate)).
Example (python 3):
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
enc = str.maketrans(alpha, key)
usrInput = 'HELLO'
print(usrInput.translate(enc))
Example (python 2)
import string
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
enc = string.maketrans(alpha, key)
inp = 'HELLO'
print string.translate(inp, enc)
Output:
LTZZE

Categories

Resources