I am trying to write a substitution encryption program where it shifts the alphabet according to a random number. This is done letter by letter or character by character
This is the error in which I get.
File "./encrypt.py", line 35, in <module>
print("after encryption: ", encrypt(text))
File "./encrypt.py", line 26, in encrypt
cipher = cipher + chr((ord(char) + str(function1()) - 65) % 27 + 65) TypeError: unsupported operand type(s) for +: 'int' and 'str'
Is there any solutions out there????
import random
text = input("enter string: ")
number = 0
number += len(text)
def encrypt(string):
def otp(filename):
file = open(filename + ".txt", "a")
file.write(str(function1()) + "\n")
file.close()
def function1():
for num in range(number):
shift = str(random.randint(1,26))
print(shift)
cipher = ''
for char in string:
if char == ' ':
cipher = cipher + chr((ord(char) + str(function1()) - 65) % 27 + 65)
otp("onetimepad")
elif char.isupper():
cipher = cipher + chr((ord(char) + str(function1()) - 65) % 27 + 65)
otp("onetimepad")
else:
cipher = cipher + chr((ord(char) + str(function1()) - 97) % 27 + 97)
otp("onetimepad")
return cipher
print("original string: ", text)
print("after encryption: ", encrypt(text))
The error message is quite clear. The cited line of code has only two + operations, and the first one clearly violates the available definitions of +
ord(char) + str(function1())
You have an integer on the left; on the right, you explicitly converted the return value to string. Decide what you're trying to do and fix your expression. It seems that you're trying to do an integer calculation of a new ordinal value. The solution may be simply to not convert the function's return value.
Related
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
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I saw someone's Ceaser cipher problem and tried to write my own. I got everything done except for the fact that my alphabet needs to wrap around
#User input
user_message = input("Input the text you would like encrypted (no
characters)")
#Cipher function
def Ciphertext(message):
cipher = ""
for i in message:
#takes each letter in message
number_code = ord(i) + 3
letter_code = chr(number_code)
cipher = cipher + letter_code
return cipher
#Unencrypted function
def Plaintext(cipher):
text = ""
#loops to get each number
for i in cipher:
#takes each letter in cipher
unencrypted_code = ord(i) - 3
unencrypted_letter_code = chr(unencrypted_code)
text = text + unencrypted_letter_code
print(text)
#Prints
print("Encrypted message")
print(Ciphertext(user_message))
print("Unencrypted message")
Plaintext(Ciphertext(user_message))
Ok so I changed my code to this:
#User input
user_message = input("Input the text you would like encrypted (no
characters)")
#Cipher function
def Ciphertext(message):
cipher = ""
for i in message:
#takes each letter in message then coverts it to number subtracts the
diffrence then converts it back into characters
number_code = ord(i) + 3
letter_code = chr(number_code)
if number_code >= ord("z"):
number_code = number_code - 123
number_code = number_code + ord("a")
letter_code = chr(number_code)
cipher = cipher + letter_code
return cipher
cipher = Ciphertext(user_message)
#Unencrypted function
def Plaintext():
text = ""
#loops to get each number
for i in cipher:
#takes each letter in cipher
unencrypted_code = ord(i) - 3
if unencrypted_code >= ord("z"):
unencryted_code = unencrypted_code + 26
unencrypted_letter_code = chr(unencrypted_code)
text = text + unencrypted_letter_code
print(text)
#Prints
print("Encrypted message")
print(Ciphertext(user_message))
print("Unencrypted message")
Plaintext()
But it continues to run this:^_` when it type in xyz
The modulo operator % returns the remainder of the division of two numbers, essentially "wrapping around" a value.
You can use this behavior to wrap your cipher around. Note that if you're using ord(), you'll be given the ASCII representation of a number - note that this is different for uppercase and lowercase letters. For example, 'A' is 65, and 'a' is 97. If you plan for your cipher to preserve the case of your letters, you'll need to subtract 65 and 97, depending on case, to properly use modulo. Try something like this:
def Ciphertext(message):
cipher = ""
for i in message:
#determine if this is an uppercase or lowercase character, and treat it accordingly
number_code = 0
if i.isupper():
number_code = (((ord(i) - 65) + 3) % 26) + 65
elif i.islower():
number_code = (((ord(i) - 97) + 3) % 26) + 97
else:
number_code = ord(i)
letter_code = chr(number_code)
cipher += letter_code
return cipher
def Plaintext(cipher):
text = ""
for i in cipher:
unencrypted_code = 0
if i.isupper():
unencrypted_code = (((ord(i) - 65) - 3) % 26) + 65
elif i.islower():
unencrypted_code = (((ord(i) - 97) - 3) % 26) + 97
else:
unencrypted_code = ord(i)
letter_code = chr(unencrypted_code)
text += letter_code
return text
print (Ciphertext("Hello world! wxyz"))
print (Plaintext("Khoor zruog! zabc"))
Try it here!
I'm having trouble trying to leave the punctuation unchanged while encrypting or decrypting a message
# encryption
message = input("Enter a message to be encrypted: ") # user inputs message to be encrypted
offset = int(input ("Enter an offset: ")) # user inputs offset
print ("\t")
encrypt = " "
for char in message:
if char == " ":
encrypt = encrypt + char
elif char.isupper():
encrypt = encrypt + chr((ord(char) + offset - 65) % 26 + 65) # for uppercase Z
else:
encrypt = encrypt + chr((ord(char) + offset - 97) % 26 + 97) # for lowercase z
print ("Your original message:",message)
print ("Your encrypted message:",encrypt)
print ("\t")
An example of what the output looks like if I try to encrypt a message with punctuation (offset of 8):
Your original message: Mr. and Mrs. Dursley, of number four Privet Drive, were proud to say that they were perfectly normal, thank you very much.
Your encrypted message: Uzj ivl Uzaj Lczatmgh wn vcujmz nwcz Xzqdmb Lzqdmh emzm xzwcl bw aig bpib bpmg emzm xmznmkbtg vwzuith bpivs gwc dmzg uckp
I suspect this program is changing the punctuation to letters due to the
chr(ord(char)) function.
Is there any way I can add in the actual punctuation to the encrypted message without changing the code too much? I would really appreciate any help, thank you!
You can get your desired result with just a one liner change by handling all non alpha characters in the first conditional using isalpha()
# encryption
message = input("Enter a message to be encrypted: ") # user inputs message to be encrypted
offset = int(input ("Enter an offset: ")) # user inputs offset
print ("\t")
encrypt = " "
for char in message:
if not char.isalpha(): #changed
encrypt = encrypt + char
elif char.isupper():
encrypt = encrypt + chr((ord(char) + offset - 65) % 26 + 65) # for uppercase Z
else:
encrypt = encrypt + chr((ord(char) + offset - 97) % 26 + 97) # for lowercase z
print ("Your original message:",message)
print ("Your encrypted message:",encrypt)
print ("\t")
Same as you do it with a space, you can do it with any character.
if char in string.punctuation+' ':
encrypt = encrypt + char
I am new to cryptography so I try to make a simple Caesar cipher program with python
but it keeps returning only one letter. Can anyone help please? Here's my code:
def main():
text = raw_input('input plainteks:')
key = int(raw_input('input key:'))
print("plain teks :"+text)
print("key :" +str(key))
print("hasil cipher:", encrypt(text,key))
def encrypt(text,key):
hasil = ''
for i in range(len(text)): #
char = text[i]
if (char.isupper()):
hasil += chr((ord(char) + key-65)%26 + 65)
else:
hasil += chr((ord(char) + key-97)%26 + 97)
return hasil
Here when I try to run it:
input plainteks:melody
input key:3
plain teks :melody
key :3
hasil cipher: b
Your if is not in the loop.
The following code works:
def main():
text = raw_input('input plainteks:')
key = int(raw_input('input key:'))
print("plain teks: "+text)
print("key: " +str(key))
print("hasil cipher: "+encrypt(text,key))
def encrypt(text,key):
hasil = ''
for i in range(len(text)): #
char = text[i]
if (char.isupper()):
hasil += chr((ord(char) + key-65)%26 + 65)
else:
hasil += chr((ord(char) + key-97)%26 + 97)
return hasil
main()
Also you can use the secretpy module
from secretpy import Caesar
text = 'melody'
key = 3
print(text)
cipher = Caesar()
enc = cipher.encrypt(text, key)
print(enc)
Hi guys Here is my error:
Phrase to be Decrypted: n
Shift keyword, Word only: ]YY
The code will write the Decryption to a file of your choice
Please input the number to decrypt by: 44
*hang*
Inputs:
Phrase: n
Keyword: ]YY
Decryption shift: 44
What it should do is decrypt the Phrase into Chicken and the keyword into Egg. The number I have input is the shift that the code performs to scramble the keyword.
Here is my code:
import getpass
import random #imports random module
import codecs #imports codecs module for encode task (UTF8)
import time
w = getpass.getpass("Input the Password: ")
with open('Password.txt') as f:
found = False
for line in f:
if w in line:
import random
import codecs
phrase = input('Phrase to be Decrypted: ') #Asks user to input a phrase
shift_key = input("Shift keyword, Word only: ") #Asks user to input a keyword
print ("The code will write the Decryption to a file of your choice")
Encryption_Base = ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890,./;:<>?'##~]}[{=+-_)(*&^%$£!`¬\|"] #Encryption base. Randint uses this.
key_encryption = int(input("Please input the number to decrypt by: ")) #Grabs a random number between 0 and 94
Cipher = '' #Cipher is blank, to be used later.
for c in shift_key: #Looks for a letter in the keyword, in this case c
if c in Encryption_Base: #Looks for the same letter in the string.
Cipher -= Encryption_Base(Encryption_Base.index(c)-(key_encryption)/(len(Encryption_Base))) #Turns the keyword into a different letter
def Keyword_Encryption(key, phrase): #Defines the new variable
if len(phrase) < len(key): #If the phrase is longer than the key
while len(phrase) < len(key): #While the phrase is longer than the key
length_to_add = len(phrase) + len(key) #Shorten the key to the length of the phrase
key = key + key[0:length_to_add]
elif len(phrase) > len(key): #However if the phrase is shorter than the key
while len(phrase) > len(key):
length_to_sub = len(key) + (len(key) + len(phrase)) #Make both of them equal.
key = key[0:length_to_sub]
else:
pass #Anything else stops the code.
shifted_phrase = '' #Shifted phrase is blank for later
for i in range(len(phrase)): #Find a letter in the length of the phrase
new_letter = (ord(key[i]) + 50) - (ord(phrase[i]) + 50) - 50 #Change the order of the key
if new_letter < 1220: #If the new letter is higher than 1220
new_letter = chr(new_letter + 26) #Create an extra character
else:
new_letter = chr(new_letter) #Anything else creates a new character (could be overflow?)
shifted_phrase = shifted_phrase - new_letter #Adds the new letter onto the encrypted phrase
return shifted_phrase
result = Keyword_Encryption(Cipher, phrase) #Adds the Cipher and phrase to keyword encryption so that the user knows what key to use to decrypt it.
print (" ")
print (":-) " * 3 + "Encrypting Phrase... " + ":-) " * 3) #All of ths makes it look pretty
print (":-) " * 3 + "Done! " + ":-) " * 3) #
print (" ") #
print ('Here is your Encrypted Phrase:' + (result) + (Cipher) + (str(key_encryption))) #Finally prints the result
time.sleep(2)
FileName = input("Enter a filename for the encrypted phrase and key to be written to: ") + ".txt"
file = codecs.open(FileName, "w", encoding = "utf8") #Opens the file Encrypted.txt and encodes it in UTF to support unicode.
file.write (str(result) + " " + (Cipher) + " " + (str(key_encryption))) #Writes the phrase and key seperately to aid the user
file.close() #Closes the file
k=input("Prompt: ")
if not found:
print("Access Denied")
time.sleep(5)
Any help would be greatly appreciated :)
EDIT:
New error:
Phrase to be Decrypted: n
Shift keyword, Word only: ]YY
The code will write the Decryption to a file of your choice
Please input the number to decrypt by: 44
Traceback (most recent call last):
File "E:\Python\Password Encryption\Decryption.py", line 56, in <module>
result = Keyword_Encryption(Cipher, phrase) #Adds the Cipher and phrase to keyword encryption so that the user knows what key to use to decrypt it.
File "E:\Python\Password Encryption\Decryption.py", line 46, in Keyword_Encryption
new_letter = (ord(key[i]) + 50) - (ord(phrase[i]) + 50) - 50 #Change the order of the key
IndexError: string index out of range