Don't know how to decode from double pair "ab" to "a" - python

I've been trying how to decode my encryption from "kl" to "a", or "klfg" to "ab"
I have tried str.find(), str.replace() and many other options, but I couldn't get any good result
My code:
print ("Welcome")
message = input("Entry text")
encoded= ""
for char in message:
if char== "a" or char == "A":
encoded += "kl"
elif char== "b" or char == "B":
encoded += "fg"
elif char== "z" or char == "Z":
encoded += "wt"
print (encoded)

You can get rid of the "if..." by building dictionaries to handle the mapping between unencoded and encoded versions of the string. Then its just a question of building the dictionary keys. When encoding, lower and upper case map to the same encoded value. When decoding, grab 2 characters at a time.
encoding = (("A", "kl"), ("B","fg"), ("C","wt"))
encodemap = {frm:to for frm,to in encoding}
decodemap = {to:frm for frm,to in encoding}
def encoder(message):
return "".join(encodemap.get(c.upper(), "??") for c in message)
def decoder(encrypted):
return "".join(decodemap.get(encrypted[i:i+2], "?")
for i in range(0, len(encrypted), 2))
e = encoder("abcABC")
print(e)
d = decoder(e)
print(d)

So if I'm reading your question correct, you're looking to decode an encrypted message like for example "klklfg", which is what you get if you input aab into your code.
If you're then looking to decode that message you can do so using the enumerate function which gives you the index as well as the character in a string
decoded = ''
for i, char in enumerate(encoded):
if char == 'k' and encoded[i + 1] == 'l':
decoded += 'a'
if char == 'f' and encoded[i + 1] == 'g':
decoded += 'b'
print(decoded)
Pasting this code after your code will decrypt your encrypted message! Again, I'm not exactly sure if that was your question but here's my answer anyways.

Not very efficient, but I think it will solve your problem:
print ("Welcome")
decrypted = ["a", "b", "z"]
encrypted = ["kl", "fg", "wt"]
encryptor = dict(zip(decrypted, encrypted))
decryptor = dict(zip(encrypted, decrypted))
message = input("Entry text:\n")
encoded = ""
for char in message:
encoded += encryptor.get(char, "?")
print("Encoded:", encoded)
decoded = ""
start = 0
end = 1
while start < end and start < len(encoded):
while end <= len(encoded):
substr = encoded[start:end]
if substr in encrypted:
decoded += decryptor.get(substr, "?")
start = end
end = start + 1
else:
end += 1
print("Decoded:", decoded)

Related

How to avoid backspace/delete/null when print cipher text?

I am testing a substitution cipher. I'm using the 256 standard ASCII. Here's my code:
def Encrypt(psw, key):
res = ""
for i in psw:
new_letter = chr((ord(i)+key)%255)
if new_letter == '\n':
new_letter = '。'
res += new_letter
return res
def Decrypt(psw, key):
res = ""
for i in psw:
if i == '。':
i = '\n'
old_letter = chr((ord(i)-key)%255)
res += old_letter
return res
if __name__ == "__main__":
try:
while True:
i = input("1 for encryption, 2 for decryption")
s = "";k = 0
if i == '1':
s = input("Input Plaintext:")
k = (int)(input("Input Key:"))
print("Ciphertext is:"+Encrypt(s, k))
elif i == '2':
s = input("Input Ciphertext:")
k = (int)(input("Input Key:"))
print("Plaintext is:"+Decrypt(s, k))
else:
break
except:
print("Error")
When I test some keys, such as 6012, the ciphertext is ãøôøø³ø³ûº³ú
I used this result to restore the plaintext, but failed, and it became Peasee me wh's wrong
I think this is due to special operators such as Delete, Backspace, and Null in the encryption process. It caused me to be unable to recover. Is there any way to solve this problem?
Most of the time, you should not print binary data (ciphertext) in a human-text channel (stdout) because it will interpret the non-printable data instead of displaying it.
If what you want is just to be able to copy-paste, you should escape the non-printable bits. One simple way to do it is to use urllib.parse.quote and unquote :
import urllib.parse
[...]
print("Ciphertext is: "+urllib.parse.quote(Encrypt(s, k)))
[...]
s = urllib.parse.unquote(input("Input Ciphertext:"))
Example :
1 for encryption, 2 for decryption
1
Input Plaintext:hello
Input Key:6012
Ciphertext is:%C3%BB%C3%B8%00%00%03
1 for encryption, 2 for decryption
2
Input Ciphertext:%C3%BB%C3%B8%00%00%03
Input Key:6012
Plaintext is:hello

Program failed for outputting brute force results on decryption method

def asciiShift(character, aShift):
asciiNum = ord(character) + (int(aShift))%26
return asciiNum
def stringShift(string, shift):
k=0
newstring = ''
string_len = len(string)
while k<string_len:
newstring = newstring + string[int(((int(shift)%int(string_len))+k))%int(string_len)]
k=k+1
if k==string_len:
break
return newstring
def encrypt(message, aShift, sShift):
i=0
length = len(message)
asciiChars = []
while i<length:
asciiChars.append(asciiShift(message[i].upper(), aShift))
i=i+1
if i==length:
break
string = ''
j=0
while j<length:
string = string + str(chr(asciiChars[j]))
j=j+1
shifted_string = stringShift(string, sShift)
print(shifted_string)
def decrypt(message):
x=0
mlength = len(message)
mstring = ''
while x<mlength:
d=0
while d<mlength:
mstring = mstring + message[int(x+d)%(mlength)]
d=d+1
e=0
mstring = mstring.upper()
mlist = []
while e<mlength:
mlist.append(ord(mstring[e]))
e=e+1
f=0
while f<26:
g=0
newstring = ''
while g<mlength:
newstring = newstring + chr(mlist[g] + f%26)
g=g+1
print(newstring)
f=f+1
x=x+1
if x==mlength:
break
# todo list
# shift string around (use.upper())
# convert shifted string to ascii number list
# add numbers from 0-25 to the ascii number list
# print out the results
typeConfirm = input("Encrypt or Decrypt? (E/D): ")
if typeConfirm[0].upper() == 'D':
decryptBool = True
elif typeConfirm[0].upper()== 'E':
decryptBool = False
else:
print("You probably said an incorrect choice or read the question incorrectly. Exiting program for now...")
exit()
if decryptBool == True:
decrypt_msg = input("What is the encoded message?: ")
decrypt(decrypt_msg)
else:
message = input("What is your message?: ")
aShift = input("ASCII shift?: ")
sShift = input("String shift?: ")
a=0
b=len(message)
while a<b:
if message[a] == '~':
print("Sorry, the encryptor doesn't support any special characters (other than the ones on a normal keyboard, or these characters that are on a keyboard: '~', '{', and '}' only these 3 characters in the quotation marks don't work. Sorry for the inconvenience!")
exit()
elif message[a] == '{':
print("Sorry, the encryptor doesn't support any special characters (other than the ones on a normal keyboard, or these characters that are on a keyboard: '~', '{', and '}' only these 3 characters in the quotation marks don't work. Sorry for the inconvenience!")
exit()
elif message[a] == '}':
print("Sorry, the encryptor doesn't support any special characters that aren't on a normal office keyboard. However, these characters that are on a keyboard don't work: '~', '{', and '}' only these 3 characters in the quotation marks don't work. Sorry for the inconvenience!")
exit()
a=a+1
if a==b:
break
encrypt(message, aShift, sShift)
I made this code so far, however for some reason, the decrypter doesn't work with the outputs of the encrypter. (As in, the brute force doesn't output the input at all)
For context, the purpose of this program would be to encrypt a string by converting all the characters to ascii code, and adding a number to it. Then, the new number would be turned back into a character, and the string would be shifted by a certain amount. For ex, "ABC" shift 1 -> [66, 67, 68] -> "BCD" shift 2 -> "DBC"
If someone could help point out why it isn't working (or if there's a better solution, ex. "you wrote this area wrong", or "the encryptor result is faulty", etc.), it would be much appreciated!
Since you indicated you just want to start out with performing a brute force algorithm to decrypt an encrypted phrase or word, the intuitive solution seemed to be to create complimentary functions for the ASCII shift and string shift functions that perform a shift in the opposite direction for the decryption function. Then, build the decryption function such that it is almost a duplicate of the encryption function except it loops through the possible shifting utilizing the complimentary functions.
Following is a revised version of your code you can experiment with.
def asciiShift(character, aShift):
asciiNum = ord(character) + (int(aShift))%26
return asciiNum
def asciiShiftx(character, aShift):
asciiNum = ord(character) - (int(aShift))%26
return asciiNum
def stringShift(string, shift):
k=0
newstring = ''
string_len = len(string)
while k<string_len:
newstring = newstring + string[int(((int(shift)%int(string_len))+k))%int(string_len)]
k=k+1
if k==string_len:
break
return newstring
def stringShiftx(string, shift):
k=0
newstring = ''
string_len = len(string)
while k<string_len:
newstring = newstring + string[int(((int(shift * -1)%int(string_len))+k))%int(string_len)]
k=k+1
if k==string_len:
break
return newstring
def encrypt(message, aShift, sShift):
i=0
length = len(message)
asciiChars = []
while i<length:
asciiChars.append(asciiShift(message[i].upper(), aShift))
i=i+1
if i==length:
break
string = ''
j=0
while j<length:
string = string + str(chr(asciiChars[j]))
j=j+1
shifted_string = stringShift(string, sShift)
print(shifted_string)
def decrypt(message):
for z1 in range(26):
for z2 in range(26):
i=0
lengthx = len(message)
asciiChars = []
while i<lengthx:
asciiChars.append(asciiShiftx(message[i].upper(), z1))
i=i+1
if i==lengthx:
break
string = ''
j=0
while j<lengthx:
string = string + str(chr(asciiChars[j]))
j=j+1
shifted_string = stringShiftx(string, z2)
print('ASCII shift: ', z1, 'String shift: ', z2, shifted_string)
typeConfirm = input("Encrypt or Decrypt? (E/D): ")
if typeConfirm[0].upper() == 'D':
decryptBool = True
elif typeConfirm[0].upper()== 'E':
decryptBool = False
else:
print("You probably said an incorrect choice or read the question incorrectly. Exiting program for now...")
exit()
if decryptBool == True:
decrypt_msg = input("What is the encoded message?: ")
decrypt(decrypt_msg)
else:
message = input("What is your message?: ")
aShift = input("ASCII shift?: ")
sShift = input("String shift?: ")
a=0
b=len(message)
while a<b:
if message[a] == '~':
print("Sorry, the encryptor doesn't support any special characters (other than the ones on a normal keyboard, or these characters that are on a keyboard: '~', '{', and '}' only these 3 characters in the quotation marks don't work. Sorry for the inconvenience!")
exit()
elif message[a] == '{':
print("Sorry, the encryptor doesn't support any special characters (other than the ones on a normal keyboard, or these characters that are on a keyboard: '~', '{', and '}' only these 3 characters in the quotation marks don't work. Sorry for the inconvenience!")
exit()
elif message[a] == '}':
print("Sorry, the encryptor doesn't support any special characters that aren't on a normal office keyboard. However, these characters that are on a keyboard don't work: '~', '{', and '}' only these 3 characters in the quotation marks don't work. Sorry for the inconvenience!")
exit()
a=a+1
if a==b:
break
encrypt(message, aShift, sShift)
I tested this out by encrypting a short phrase ("HELLO THERE") with an ASCII shift of "4" and a string shift of "22".
#Una:~/Python_Programs/Encrypt$ python3 Encrypt.py
Encrypt or Decrypt? (E/D): E
What is your message?: HELLO THERE
ASCII shift?: 4
String shift?: 22
LIPPS$XLIVI
Then, I called the program again and asked it to decrypt the encrypted phrase ("LIPPS$XLIVI"). I will skip to the portion of the terminal output where one can see the original text.
#Una:~/Python_Programs/Encrypt$ python3 Encrypt.py
Encrypt or Decrypt? (E/D): D
What is the encoded message?: LIPPS$XLIVI
. . .
ASCII shift: 4 String shift: 18 O THEREHELL
ASCII shift: 4 String shift: 19 LO THEREHEL
ASCII shift: 4 String shift: 20 LLO THEREHE
ASCII shift: 4 String shift: 21 ELLO THEREH
ASCII shift: 4 String shift: 22 HELLO THERE
ASCII shift: 4 String shift: 23 EHELLO THER
ASCII shift: 4 String shift: 24 REHELLO THE
ASCII shift: 4 String shift: 25 EREHELLO TH
As would make sense the complimentary shift values match the original shift values where one sees the correct decrypted phrase.
Anyway, experiment with that. Hope that helps.
Regards.

Encoding a password with special characters

I am in an into to Programming class and the assignment is in part to shift the letters of a valid password by +1 if it is a letter or number and -1 if it is a !##$ special character. I have most of it working with my below code but I always get the wrong output for the special characters. If I use to the code of anything high like 128 then I get the wrong symbol.
I am using the code from an encryption program from the other week and slowly changing things but I feel like this is too involved for something simple
If I enter the password UMA#augusta2020 I need to get the output VNB?bvhvtub3131 but I either end up with a space, b, or wrong symbol when I change the code input between 26,64,96,128, etc.
I have updated the code to fix small errors
def main():
print("This program validates and encrypts a password")
print()
main()
# The Encryption Function
def cipher_encrypt(plain_text):
encrypted = ""
for c in plain_text:
if c.isupper(): #check if it's an uppercase character
c_index = ord(c) - ord('A')
# shift the current character by key positions
c_shifted = (c_index + 1) % 26 + ord('A')
c_new = chr(c_shifted)
encrypted += c_new
elif c.islower(): #check if its a lowecase character
c_index = ord(c) - ord('a')
c_shifted = (c_index + 1) % 26 + ord('a')
c_new = chr(c_shifted)
encrypted += c_new
elif c.isdigit():
# if it's a number,shift its value
c_new = (int(c) + 1) % 10
encrypted += str(c_new)
else:
# if its neither alphabetical nor a number, -1
c_shifted = (c_index - 1) % 128 + ord('a')
c_new = chr(c_shifted)
encrypted += c_new
return encrypted
plain_text =input("Enter your Password: ")
print()
ciphertext = cipher_encrypt(plain_text)
print()
print("Your Password: ", plain_text)
print()
print("Your password is valid and encrypted it is: ", ciphertext)
print()
Here is a much cleaner approach:
def cipher_encrypt(plain_text):
alpha = 'abcdefghijklmnopqrstuvwxyz'
digits = '0123456789'
puncs = '!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~'
encrypted_text = ''
for c in plain_text:
if c.lower() in alpha:
c_index = alpha.index(c.lower())
e_index = (c_index + 1)%len(alpha)
if c == c.lower():
encrypted_text += alpha[e_index]
else:
encrypted_text += alpha[e_index].upper()
elif c in digits:
c_index = digits.index(c)
e_index = (c_index + 1)%len(digits)
encrypted_text += digits[e_index]
else:
c_index = puncs.index(c)
e_index = (c_index +len(puncs) - 1)%len(puncs)
encrypted_text += puncs[e_index]
return encrypted_text
In this approach I deal with each caharcter in plain text by:
Determining idf the char is part of alpha by making use of the c.lower() function to isolate alpha chars and then find an index modulo the len of alpha. Then I determine if I need an uppercase char or lower case in the encrypted text.
I use the same modulo approach for digits, but don't have to worry about upper and lower, finally
I find the index for the punctuations found in the plain_text

Python Vigenere Cipher Encrypt method not encrypting properly

The encrypt method in my program is not encrypting correctly. I thought I figured out why using debug mode; it's because it reads the spaces between words as something it has to encrypt. So I tried typing a message without spaces but it still didn't come out correctly.
I figure the issue is the if statement with the key. I tried commenting lines out, changing statements, changing the if statement to a for loop, but it still isn't correct.
def main():
vig_square = create_vig_square()
message = input("Enter a multi-word message with punctuation: ")
input_key = input("Enter a single word key with no punctuation: ")
msg = message.lower()
key = input_key.lower()
coded_msg = encrypt(msg, key, vig_square)
print("The encoded message is: ",coded_msg)
print("The decoded message is: ", msg)
def encrypt(msg,key,vig_square):
coded_msg = ""
key_inc = 0
for i in range(len(msg)):
msg_char = msg[i]
if key_inc == len(key)-1:
key_inc = 0
key_char = key[key_inc]
if msg_char.isalpha() and key_char.isalpha():
row_index = get_row_index(key_char,vig_square)
col_index = get_col_index(msg_char,vig_square)
coded_msg = coded_msg+vig_square[row_index][col_index]
else:
coded_msg = coded_msg + " "
key_inc = key_inc+1
return coded_msg
def get_col_index(msg_char, vig_square):
column_index = ord(msg_char) - 97
return column_index
def get_row_index(key_char, vig_square):
row_index = ord(key_char) - 97
return row_index
def create_vig_square():
vig_square = list()
for row in range(26):
next_row = list()
chr_code = ord('a') + row
for col in range(26):
letter = chr(chr_code)
next_row.append(letter)
chr_code = chr_code + 1
if chr_code > 122:
chr_code = ord('a')
vig_square.append(next_row)
return vig_square
main()
This example was given to us:
Enter a multi-word message with punctuation: The eagle has landed.
Enter a single word key with no punctuation: LINKED
The encoded message is: epr oejwm ukw olvqoh.
The decoded message is: the eagle has landed.
But my encoded message comes out as:
epr iloyo sif plvqoh
You have two errors:
First, you don't use all characters in the key. Change the following line:
if key_inc == len(key)-1:
key_inc = 0
to
if key_inc == len(key):
key_inc = 0
Second, you move the key pointer even if you process a non-alpha character in the message (e.g. spaces). Do it only if you encode a character, i.e. make the following change:
if msg_char.isalpha() and key_char.isalpha():
...
key_inc = key_inc+1 # Move this line here
else:
...

Interactive rot13 cipher

I have a code and I'm having trouble making it interactive.
Here's the problem:
"""Write a function called rot13 that uses the Caesar cipher to encrypt a message. The Caesar cipher works like a substitution cipher but each character is replaced by the character 13 characters to “its right” in the alphabet. So for example the letter “a” becomes the letter “n”. If a letter is past the middle of the alphabet then the counting wraps around to the letter “a” again, so “n” becomes “a”, “o” becomes “b” and so on. Hint: Whenever you talk about things wrapping around its a good idea to think of modulo arithmetic (using the remainder operator)."""
Here's the code to this problem:
def rot13(mess):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
encrypted = ''
for char in mess:
if char == ' ':
encrypted = encrypted + ' '
else:
rotated_index = alphabet.index(char) + 13
if rotated_index < 26:
encrypted = encrypted + alphabet[rotated_index]
else:
encrypted = encrypted + alphabet[rotated_index % 26]
return encrypted
def main():
print(rot13('abcde'))
print(rot13('nopqr'))
print(rot13(rot13('since rot thirteen is symmetric you should see this message')))
if __name__ == "__main__":
main()
I want to make it interactive where you can input any message and you can rotate the letters however many times as you want. Here is my attempt. I understand you'd need two parameters to pass, but I'm clueless as to how to replace a few items.
Here's my attempt:
def rot13(mess, char):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
encrypted = ''
for char in mess:
if char == ' ':
encrypted = encrypted + ' '
else:
rotated_index = alphabet.index(char) + mess
if rotated_index < 26:
encrypted = encrypted + alphabet[rotated_index]
else:
encrypted = encrypted + alphabet[rotated_index % 26]
return encrypted
def main():
messy_shit = input("Rotate by: ")
the_message = input("Type a message")
print(rot13(the_message, messy_shit))
if __name__ == "__main__":
main()
I don't know where my input should be taking place in the function. I have a feeling it could be encrypted?
This is probably what you're looking for. It rotates the message by the messy_shit input.
def rot13(mess, rotate_by):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
encrypted = ''
for char in mess:
if char == ' ':
encrypted = encrypted + ' '
else:
rotated_index = alphabet.index(char) + int(rotate_by)
if rotated_index < 26:
encrypted = encrypted + alphabet[rotated_index]
else:
encrypted = encrypted + alphabet[rotated_index % 26]
return encrypted
def main():
messy_shit = input("Rotate by: ")
the_message = input("Type a message")
print(rot13(the_message, messy_shit))
def rot(message, rotate_by):
'''
Creates a string as the result of rotating the given string
by the given number of characters to rotate by
Args:
message: a string to be rotated by rotate_by characters
rotate_by: a non-negative integer that represents the number
of characters to rotate message by
Returns:
A string representing the given string (message) rotated by
(rotate_by) characters. For example:
rot('hello', 13) returns 'uryyb'
'''
assert isinstance(rotate_by, int) == True
assert (rotate_by >= 0) == True
alphabet = 'abcdefghijklmnopqrstuvwxyz'
rotated_message = []
for char in message:
if char == ' ':
rotated_message.append(char)
else:
rotated_index = alphabet.index(char) + rotate_by
if rotated_index < 26:
rotated_message.append(alphabet[rotated_index])
else:
rotated_message.append(alphabet[rotated_index % 26])
return ''.join(rotated_message)
if __name__ == '__main__':
while True:
# Get user input necessary for executing the rot function
message = input("Enter message here: ")
rotate_by = input("Enter your rotation number: ")
# Ensure the user's input is valid
if not rotate_by.isdigit():
print("Invalid! Expected a non-negative integer to rotate by")
continue
rotated_message = rot(message, int(rotate_by))
print("rot-ified message:", rotated_message)
# Allow the user to decide if they want to continue
run_again = input("Continue? [y/n]: ").lower()
while run_again != 'y' and run_again != 'n':
print("Invalid! Expected 'y' or 'n'")
run_again = input("Continue? [y/n]: ")
if run_again == 'n':
break
Note: It's more efficient to create a list of characters then join them to produce a string instead of using string = string + char. See Method 6 here and the Python docs here. Also, be aware that our rot function only works for lowercase letters of the alphabet. It'll break if you try to rot a message with uppercase characters or any character that isn't in alphabet.

Categories