Need To Write Program to Decode Alphabet for Secret Message [closed] - python

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
So, I need to input a scrambled alphabet, and then input a secret message using that alphabet. My program needs to unscramble the secret message. I have written this so far and am stuck. I was hoping someone could help me. What I tried so far is changing every index in the list to A-Z. My question is how do I use what I wrote for that and make it work for the secret message I input as well.
s = ()
alphabet = input("Please input the scrambled alphabet in order: ")
message = input("Now input the scrambled message: ")
alphabet.upper()
s = dict(alphabet)
num = 1
while num < 2:
s[0] = chr(65)
s[1] = chr(66)
s[2] = chr(67)
s[3] = chr(68)
s[4] = chr(69)
s[5] = chr(70)
s[6] = chr(71)
s[7] = chr(72)
s[8] = chr(73)
s[9] = chr(74)
s[10] = chr(75)
s[11] = chr(76)
s[12] = chr(77)
s[13] = chr(78)
s[14] = chr(79)
s[15] = chr(80)
s[16] = chr(81)
s[17] = chr(82)
s[18] = chr(83)
s[19] = chr(84)
s[20] = chr(85)
s[21] = chr(86)
s[22] = chr(87)
s[23] = chr(88)
s[24] = chr(89)
s[25] = chr(90)
num +=1
print (s)
for alpha in message.upper():
if alpha < "A" or alpha > "Z":
print(alpha,end="")
else:
print(s [ord(alpha) -65 ], end="")

First, creating the big dictionary s is entirely unnecessary. It literally does nothing: the line:
s [ord(alpha) -65 ]
Is turning a letter into a number, subtracting 65, and then putting it through a dictionary that adds 65 and turns it back into a number.
Secondly, the line alphabet.upper() doesn't actually change the alphabet, it just returns an uppercase version. You need to do
alphabet = alphabet.upper()
Now for the meaty part. What you meant to do was create a dictionary mapping letters in the code alphabet to letters in the real alphabet. The line dict(alphabet) doesn't do this. Instead, iterate through the characters in the string and assign each to the corresponding letter. You're on the right track using chr, but are going to way too much work. How about this:
s = {}
for i in range(26): # iterate from 0 to 25
s[alphabet[i]] = chr(65 + i)
since chr(65 + i) is the letter in the normal, ordered alphabet, and alphabet[i] is the scrambled one.
Once you have that dictionary, running through letter by letter and changing it should be easy (and it's left to you).

You could use the string translate() method:
import string
intab = 'abcdefghijklmnopqrstuvwxyz' # or string.ascii_lowercase
outtab = 'xyzabcdefghijklmnopqrstuvw'
tab = string.maketrans(intab, outtab)
s = raw_input('Type some text: ').lower()
print s.translate(tab)
maketrans() creates a table with both alphabets, and translate() just replace each character of the string by its pair in the table.

I don't know Python - this is pseudocode
create array of scrambled alphabet
create array of "normal" alphabet
foreach char in message, find char in scrambled array, then output corresponding "normal" char

You could make a dictionary:
alphabet({'a':'alpha', 'b':'bravo','c':'charlie', etc.})
so abc would translate to alphabravocharlie
where 'a','b',.. are the coded letters and 'alpha','bravo',... are their actual values. Make "cypher" by reversing this.
See the section of online tutorials on dictionaries:
http://docs.python.org/dev/library/collections.html

I believe you're asking 'If I type in a string of characters (I'm assuming a string with no delimiter), how can I make that a dictionary where the first letter = A, the second = B, etc.' (sorry if this is the incorrect interpretation). If that is the case, you could do something like this (note the usage of raw_input - input is a built-in that evaluates the parameter - it will not assign):
alphabet = raw_input("Please input the scrambled alphabet in order: ")
message = raw_input("Now input the scrambled message: ")
secret_map = {}
# Step through the provided string, incrementing the character number by index.
# Index will start at 65 + 0 = A (change to 98 if you want lowercase)
for index, letter in enumerate(alphabet):
secret_map[letter] = chr(65 + index)
# Now join the string together, mapping each letter to its corresponding value
new_str = ''.join([secret_map[char] for char in message])
# Print the resulting string
print new_str
Since this is homework (and perhaps you haven't gotten to list comprehensions), this is equivalent to creating new_str:
new_str = ''
for letter in message:
new_str += secret_map[letter]
Let me know if this isn't what you were looking for.

I just couldn't resist expanding on stummjr's answer to create a more pythonic version of both encoding and decoding (I added some extra variables to try and make each step more clear):
import random, string
cypher_list = list(string.ascii_lowercase)
random.shuffle(cypher_list)
cypher_text = ''.join(cypher_list)
encode_tab = string.maketrans(string.ascii_lowercase, cypher_text)
decode_tab = string.maketrans(cypher_text, string.ascii_lowercase)
orig_text = 'this means war'
crypt_text = orig_text.translate(encode_tab)
clear_text = crypt_text.translate(decode_tab)
print cypher_text
print crypt_text
print clear_text
assert(clear_text == orig_text)

Related

How to add a letter after every letter in a string?

I want to create an encryption script that encrypts the string given to it, here's how it went.
# First, I created a list of the string I got
string = '16271'
string_list = []
for letter in string:
string_list.append(letter)
Then, I have a list called encrypt_list which the letters which I want to add in order to encrypt my string.
So, I use the following code to add a random letter from the encrypt_list after each letter/component in the string_list and then join the list and print as a string.
for i in range(0, len(string) - 1):
string_list.insert(for letter in string_list: string_list.index(letter) + 1, encrypt_list[random.randint(0, len(encrypt_list) - 1)])
print("The encrypted string is: ")
print(''.join(string_list))
I expected the output to be: 1A6b2n781 (I bolded the letter to show my actual string in it) But I am getting an error, that I cannot use the for loop in the insert function, and I cannot find another way of doing that, please help. Hope I make my problem clear
Not sure what your encrypted_list looks like, but if it's a list of letters, this would work:
import random
string = '16271'
encrypted_list = ['r', 't', 's', 'o', 'j', 'e']
encrypted_string = ''.join([s + random.choice(encrypted_list) for s in string])
Something like this?
# First, I created a list of the string I got
import random
string = '16271'
string_list = []
for letter in string:
string_list.append(letter)
the_other_list = ['lorem', 'dorem', 'forem', 'borem']
for i in range(0, len(the_other_list)):
the_other_list[i] = string_list[random.randint(0, len(string_list) - 1)] + the_other_list[i]
print(''.join(the_other_list))
Result example: 1lorem2dorem2forem7borem
You can use a for loop, adding one letter to the list at a time, then adding a randomly selected letter immediately afterwards (if we're not processing the last letter in the list). I've used constants from string to define the space of characters to sample from; you can adjust this as you see fit.
This should be simpler than trying to do repeated insertion in the middle of the list (where you'd have to handle memory shifting as you're inserting, plus it'd get slower for larger texts because you'd be attempting to insert in the middle of a list).
# First, I created a list of the string I got
import random
import string
encrypt_text = string.ascii_uppercase + string.ascii_lowercase + string.digits
plaintext = '16271'
letters = []
for index, letter in enumerate(plaintext):
letters.append(letter)
if index != len(plaintext) - 1:
letters.append(random.choice(encrypt_text))
print("The encrypted string is: ")
print(''.join(letters))
Based on how you defined the problem, I would recommend implementing it as a generator:
import random
import string
def _gen_string(s):
alphabet = string.ascii_letters
for c in s:
yield c
yield random.choice(alphabet)
Then you can use that as the basis for your encryption:
def encrypt(s):
return ''.join(_gen_string(s))
encrypt('16271')
# 1J6P2U7Z1i
Of course, this is not really encryption. It's obscurity and obscurity is not a form of security that should be relied upon :-)

How can I replace every letter in a string with something else? (Python 3) [duplicate]

This question already has answers here:
replace all characters in a string with asterisks
(4 answers)
Closed 2 years ago.
I have to develop a hangman game as part of a school assignment, and I'm trying to create a new string that will output the word to be guessed as just stars. e.g hello would be ****. Below is the code I have tried, the output seems to be only the last letter of the string to be replaced with a star, but the rest of the string is seemingly untouched:
word_to_guess = input("Enter a word for player 2 to guess:")
def guess_the_word(word_to_guess):
for letter in word_to_guess:
number_of_letters = word_to_guess.replace(letter, '*') #Taking the original string and replacing each letter with a star, giving player 2 an indicator of how many letters there are to guess
print("{} is the word for today".format(number_of_letters))
Any pointers as to where I went wrong will be appreciated
Just try
'*' * len(word_to_guess)
which will multiply the * with the length of word_to_guess.
You are reassigning the output of word_to_guess.replace, so each time it's for a single operation:
word = 'hello'
output = word.replace('h', '*')
# *ello
output = word.replace('e', '*')
# h*llo
# and so on
You probably just need
def guess_the_word(word):
letters = ''
for char in word:
letters += '*'
print(letters)
Or
def word_to_guess(word):
return ''.join('*' for char in word)
A better way to get a hashed version the same length as the word may be by using the length property.
Example:
word = "sponge"
hashedWord = ''
hashedWord += '#'*len(word)
print(f"Hashed word: {hashedWord}")
Output:
Hashed word: ######

python string.split() and loops

disclaimer im new to python
i need to split a string input send if to a function that substitutes a character in the string with a different character (like a substitution cipher) but i just dont know how to go about this
print('Welcome to the encryption protocol for top secret governemt cover ups')
string=input('whats your message?')
def encrypt(string):
alpha = "abcdefghijklmnopqrstuvwyz"
sub_alpha = "pokmenliuytrwqazxcvsdfgbhn"
index=0
while index < len(string):
letter=string[index]
im not really sure what im doing im really bad at python, this has had me stumped for 3 days now ive reviewed my course material and tried videos on youtube im probably just really really dumb
I think the key piece of knowledge you're missing is that strings are iterable. So you can do things like:
for c in "FOO":
print(c)
# prints "F\nO\nO\n"
And you can find the index of a character within a string with str.index. So you can build up your cyphertext like this:
alpha = "abcdefghijklmnopqrstuvwyz "
cypher = "pokmenliuytrw qazxcvsdfgbhn"
plaintext = "some string"
cyphertext = ""
for c in plaintext:
char_index = alpha.index(c)
cyphertext += cypher[char_index]
You can also iterate over things inline - this is called a comprehension. So to transform your string you can do this instead of using the for loop:
cyphertext = "".join(cypher[alpha.index(c)] for c in plaintext)
The example above uses the str.join function to concatenate each character of cyphertext.
Here is a solution that asks the question and then iterates through each letter, finding the index in the alpha key, and replacing it with the sub_alpha key equivalent.
Note this example also checks if it should be lowercase or uppercase.
EDIT: if the input character does not have a valid cipher, it doesn't get altered.
EDIT 2: expanded answer to convert both forwards and backwards.
alpha = "abcdefghijklmnopqrstuvwyz"
sub_alpha = "pokmenliuytrwqazxcvsdfgbhn"
def encrypt(in_char):
is_lower_case = in_char.islower()
index = alpha.find(in_char.lower())
if index < 0:
return in_char
elif is_lower_case:
return sub_alpha[index]
else:
return sub_alpha[index].upper()
def decrypt(in_char):
is_lower_case = in_char.islower()
index = sub_alpha.find(in_char.lower())
if index < 0:
return in_char
elif is_lower_case:
return alpha[index]
else:
return alpha[index].upper()
print('Welcome to the encryption protocol for top secret governemt cover ups')
input_str=input('whats your message? ')
output_str=""
for letter in input_str:
output_str += encrypt(letter)
print("Encrypted: ")
print(output_str)
input_str=""
for letter in output_str:
input_str+= decrypt(letter)
print("Decrypted: ")
print(input_str)

Selecting specific int values from list and changing them

I have been playing with Python and came across a task from MIT, which is to create coded message (Julius Cesar code where for example you change ABCD letters in message to CDEF). This is what I came up with:
Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))
listPhrase = list(Phrase)
listLenght = len(listPhrase)
ascii = []
for ch in listPhrase:
ascii.append(ord(ch))
print (ascii)
asciiCoded = []
for i in ascii:
asciiCoded.append(i+shiftValue)
print (asciiCoded)
phraseCoded = []
for i in asciiCoded:
phraseCoded.append(chr(i))
print (phraseCoded)
stringCoded = ''.join(phraseCoded)
print (stringCoded)
The code works but I have to implement not shifting the ascii value of spaces and special signs in message.
So my idea is to select values in list in range of range(65,90) and range(97,122) and change them while I do not change any others. But how do I do that?
If you want to use that gigantic code :) to do something as simple as that, then you keep a check like so:
asciiCoded = []
for i in ascii:
if 65 <= i <= 90 or 97 <= i <= 122: # only letters get changed
asciiCoded.append(i+shiftValue)
else:
asciiCoded.append(i)
But you know what, python can do the whole of that in a single line, using list comprehension. Watch this:
Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))
# encoding to cypher, in single line
stringCoded = ''.join(chr(ord(c)+shiftValue) if c.isalpha() else c for c in Phrase)
print(stringCoded)
A little explanation: the list comprehension boils down to this for loop, which is easier to comprehend. Caught something? :)
temp_list = []
for c in Phrase:
if c.isalpha():
# shift if the c is alphabet
temp_list.append(chr(ord(c)+shiftValue))
else:
# no shift if c is no alphabet
temp_list.append(c)
# join the list to form a string
stringCoded = ''.join(temp_list)
Much easier it is to use the maketrans method from the string module:
>>import string
>>
>>caesar = string.maketrans('ABCD', 'CDEF')
>>
>>s = 'CAD BA'
>>
>>print s
>>print s.translate(caesar)
CAD BA
ECF DC
EDIT: This was for Python 2.7
With 3.5 just do
caesar = str.maketrans('ABCD', 'CDEF')
And an easy function to return a mapping.
>>> def encrypt(shift):
... alphabet = string.ascii_uppercase
... move = (len(alphabet) + shift) % len(alphabet)
... map_to = alphabet[move:] + alphabet[:move]
... return str.maketrans(alphabet, map_to)
>>> "ABC".translate(encrypt(4))
'EFG'
This function uses modulo addition to construct the encrypted caesar string.
asciiCoded = []
final_ascii = ""
for i in ascii:
final_ascii = i+shiftValue #add shiftValue to ascii value of character
if final_ascii in range(65,91) or final_ascii in range(97,123): #Condition to skip the special characters
asciiCoded.append(final_ascii)
else:
asciiCoded.append(i)
print (asciiCoded)

word separator for python coding [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
So the question reads:
Write a program that accepts as input a sentence in which all of the words are run together but the first character of each word is uppercase. Convert the sentence to a string in which the words are separated by spaces and only the first word starts with an uppercase letter. For example the string "StopAndSmellTheRoses." would be converted to " Stop and smell the roses."
I am so confused this my code so far.
def main():
#User enters a sentence
my_string=input('enter a sentence: ')
print(my_string.capitalize())
main()
You can loop through the string and add a character each time to a result:
my_string = "StopAndSmellTheRoses"
i = 0
result = ""
for c in my_string:
if c.isupper() and i > 0:
result += " "
result += c.lower()
else:
result += c
i += 1
print result
We'll use c for each character as we walk through the string and we'll use i to keep track of the position in the string.
There are two possibilities: it's either an uppercase character (excluding the first one) or it's not.
In the first case we'll add a space and that character as lowercase to the result. This ensures a space is inserted before each uppercase character further in the sentence.
In the second case it's a lowercase character or the uppercase character at the beginning of the sentence. We don't have to do anything with these and we'll add it right away.
Lastly we add one to i whenever we're done with a character (i += 1) as this means we correctly know where we are in the sentence.
Welcome to SO!
One way to do this is to loop through your string, checking the chars one by one:
#You've learned how to iterate through something, right?
i = 0 #a counter
for c in my_string: #get the characters of my_string, one by one.
if c.isupper(): #check if it's in upper case
if i == 0: #if it's the first letter
new_string += c #let it be like the original
else:
new_string += ' '+.lower() #it's not the first letter,
#so add space, and lower the letter.
else:
new_string += c #else, only add the letter to the new string
i += 1
Edit added a double-check to see if it's the first letter of the sentence or not. Updated demo.
As an alternative to using a counter, you can also use the built-in function enumerate, which returns a tuple of index and values.
for i,c in enumerate(my_string): #get the characters of my_string, one by one.
if c.isupper(): #check if it's in upper case
if i == 0: #if it's the first letter
new_string += c #let it be like the original
else:
new_string += ' '+c.lower() #it's not the first letter,
#so add space, and lower the letter.
else:
new_string += c #else, only add the letter to the new string
Demo
>>> my_string = 'ImCool'
>>> new_string = ''
>>> i = 0 #a counter
>>> for c in my_string: #get the characters of my_string, one by one.
if c.isupper(): #check if it's in upper case
if i == 0: #if it's the first letter
new_string += c #let it be like the original
else:
new_string += ' '+.lower() #it's not the first letter,
#so add space, and lower the letter.
else:
new_string += c #else, only add the letter to the new string
i += 1
>>> new_string
'Im cool'
Hope this helps!
You'll need a bit of regex.
import re
split = re.findall(r'[A-Z][a-z\.]+', 'HelloThisIsMyString.')
You'll also need to join those together (inserting spaces)
' '.join(...)
and handle case conversions
' '.join(word.lower() for word in split)
(and as you already did, capitalize the first word)
' '.join(word.lower() for word in split).capitalize()
It appears that you are a little confused and this is to be expected if you are new to Python. I'm assuming you take input from the user as opposed to input for a function. Either way I would create a simple function that you could insert the users input into. The function below will accomplish what the problem asks.
def sentenceSplitter(sentence):
result = ""
for i, x in enumerate(sentence): #i is character index, x is the element
if i == 0:
result = result + x
elif x.isupper() == False: #if element is not uppercase, add it to the result
result = result + x
else: # Otherwise, add a space and lowercase the next letter
result = result + " " +x.lower()
return(result)
To reiterate, if you are looking to print out the sentence you would write this after the function:
def main():
#User enters a sentence
my_string=input('enter a sentence: ')
print(sentenceSplitter(my_string))
main()
If you are still confused feel free to ask any further questions.

Categories

Resources