Encryption algorithm randomly replaces some letters - python-3.x

I have the following python code:
file = open("encryption.txt","r")
str1 = file.read()
file.close
charList = []
for char in str1:
charList.append(char)
bits = []
ascList = []
for i in range(len(charList)):
ascList.append(ord(charList[i]))
ascList[i] = "{0:08b}".format(ascList[i])
currentAsc = ascList[i]
currentStr = str(currentAsc)
for x in range(len(currentStr)):
currentChar = currentStr[x]
bits.append(int(currentChar))
keyChar = input("enter the character that should act as the key: ")
keyAsc = "{0:08b}".format(ord(keyChar))
keyStr = str(keyAsc)
keyBits = []
for x in range(len(keyStr)):
keyBits.append(int(keyStr[x]))
key = []
while len(key) != len(bits):
for i in range(len(keyBits)):
key.append(keyBits[i])
resultBits = []
for i in range(len(bits)):
if key[i] != bits[i]:
resultBits.append("1")
else:
resultBits.append("0")
resultSplitInt = []
resultInt = ''.join(resultBits)
for i in range(0,len(resultInt), 8):
resultSplitInt.append(resultInt[i:i+8])
resultSplit = []
for i in range(len(resultSplitInt)):
resultSplit.append(chr(int(resultSplitInt[i],2)))
result = ''.join(resultSplit)
file = open("encryption.txt","w")
print(str1)
print("--------------------")
print(result)
file.write(result)
print("done")
file.close()
running the program once should change the contents of "encryption.txt" based on the key, and running the program again should return the contents to their original form.
however, when I actually run the code, some letters are swapped out.
for example:
if the contents are "hello world"
and I use the key "a"
after running the code twice I am left with "hekko workd"
why does this happen, and how can I fix it?
p.s. I am aware that this is neither a secure encryption algorithm nor is my code very efficient. I am new to python and thought this would be a fun task to try. I got this far and can't find any reasons why it isn't working

Since you operate outside ASCII range, you should open the file in binary mode: open("encryption.txt","rb") and open("encryption.txt","wb")
However, in binary mode you get a byte array from the file, not a string:
file = open("encryption.txt","rb")
str1 = file.read()
file.close()
charList = []
for char in str1:
charList.append(char)
bits = []
ascList = []
for i in range(len(charList)):
ascList.append(charList[i])
ascList[i] = "{0:08b}".format(ascList[i])
currentAsc = ascList[i]
currentStr = str(currentAsc)
for x in range(len(currentStr)):
currentChar = currentStr[x]
bits.append(int(currentChar))
keyChar = input("enter the character that should act as the key: ")
keyAsc = "{0:08b}".format(ord(keyChar))
keyStr = str(keyAsc)
keyBits = []
for x in range(len(keyStr)):
keyBits.append(int(keyStr[x]))
key = []
while len(key) != len(bits):
for i in range(len(keyBits)):
key.append(keyBits[i])
resultBits = []
for i in range(len(bits)):
if key[i] != bits[i]:
resultBits.append("1")
else:
resultBits.append("0")
resultSplitInt = []
resultInt = ''.join(resultBits)
for i in range(0,len(resultInt), 8):
resultSplitInt.append(resultInt[i:i+8])
resultSplit = []
for i in range(len(resultSplitInt)):
resultSplit.append(chr(int(resultSplitInt[i],2)))
result = ''.join(resultSplit)
file = open("encryption.txt","wb")
print(str1)
print("--------------------")
print(result)
file.write(result.encode())
print("done")
file.close()

Close the file;
file = open("encryption.txt","r")
str1 = file.read()
file.close()
Then it works.
By the way, at least use 'a'='A'

Related

White Spaces issue while converting to binary

I'm implementing A5/1 algorithm, I have the following function:
def to_binary(plain):
print(plain)
binary = str(''.join(format(ord(x), 'b') for x in plain))
j = len(binary)
binary_values = []
k = 0
while(k < j):
binary_values.insert(k,int(binary[k]))
k = k + 1
return(binary_values)
then I'm reading the input as the following:
plainText = input("Please enter your plaintext : ")
print ("You entered : "+ plainText)
plainText = to_binary(plainText)
After that I generate a keyStream and I store it in a list, then I obtain the ciphered text as the following:
while(i < len(plainText)):
cipherText = cipherText + str(plainText[i] ^ keyStream[i])
i = i + 1
Now I can decrypt the ciphered text using the following function:
def decrypt(cipher,keystream):
s = ""
binary = []
i = 0
while(i<len(cipher)):
binary.insert(i,int(cipher[i]))
s = s + str(binary[i]^keystream[i])
i = i +1
print(s)
return convert_binary_to_str(s)
and the convert_binary_to_str function is:
def convert_binary_to_str(bin_data):
str_data =' '
for i in range(0, len(bin_data), 7):
temp_data = bin_data[i:i + 7]
decimal_data = BinaryToDecimal(temp_data)
str_data = str_data + chr(decimal_data)
return str_data
Everything is working fine if the input was a sentence with no white spaces, but if the sentence was for example "Hello There", the decryption is corrupted because the white space representation in binary this way is taking "6 bits" while the other alphabetical characters are "7-bits" long, what can I do to solve this?? I need to store the plain text in a list to apply the algorithm.

How to append string values in dynamically created lists using Python?

Have been trying to append str values in different lists with for loop. Below is my effrot Please help me to figure this out.
directors_1 = [] directors_2 = [] directors_3 = [] directors_4 = []
director = dict()
for director_no in range(0, 4):
if container.find_all('p')[2].find_all('a', href=True)[director_no]['href'][-11:] == 'adv_li_dr_'+str(director_no):
director[director_no+1] = (container.find_all('p')[2].find_all('a', href=True)[director_no].text).strip()
d = director[1]
"directors_" + str(director_no+1).append(d) #Problem with this line
else:
"directors_" + str(director_no+1).append('NA')

Caesar Cipher shift on new lines

I am having a problem with my code trying to do an advanced caesar cipher shift. I changed a certain letter to another, and then added a string to certain parts of a file before encoding, but am having problems doing the shifting now. This is my code:
import string
import sys
count = 1
cont_cipher = "Y"
#User inputs text
while cont_cipher == "Y":
if count == 1:
file = str(input("Enter input file:" ""))
k = str(input("Enter shift amount: "))
purpose = str(input("Encode (E) or Decode (D) ?: "))
#Steps to encode the message, replace words/letter then shift
if purpose == "E":
my_file = open(file, "r")
file_contents = my_file.read()
#change all "e"s to "zw"s
for letter in file_contents:
if letter == "e":
file_contents = file_contents.replace(letter, "zw")
#add "hokie" to beginning, middle, and end of each line
lines = file_contents.split('\n')
def middle_message(lines, position, word_to_insert):
lines = lines[:position] + word_to_insert + lines[position:]
return lines
new_lines = ["hokie" + middle_message(lines[x], len(lines[x])//2, "hokie") + "hokie" for x in range(len(lines))]
#math to do the actual encryption
def caesar(word, shifts):
word_list = list(new_lines)
result = []
s = 0
for c in word_list:
next_ord = ord(c) + s + 2
if next_ord > 122:
next_ord = 97
result.append(chr(next_ord))
s = (s + 1) % shifts
return "".join(result)
if __name__ == "__main__":
print(caesar(my_file, 5))
#close file and add to count
my_file.close()
count = count + 1
The error I am getting is:
TypeError: ord() expected a character, but string of length 58 found
I know that I need to split it into individual characters, but am not sure how to do this. I need to use the updated message and not the original file in this step...

UnboundLocalError: local variable 'patroon' referenced before assignment

I'll start by a simplified explanation of what my code (function) has to do:
I get a file with words in it that I have to code to morse code, so I have another file where each character has a morse code. My problem occurs when I want to put each word in a dictionary as a key with as value that morse code.
to get the pattern of the code and assign it to that word in my dictionary I use another function but it says 'UnboundLocalError: local variable 'patroon' referenced before assignment'
while 'patroon' is actually my other function:
def patroon(woord, morse_dict, complement = False, spiegel = False):
patroon_str = ''
for letter in woord:
patroon_str += morse_dict[letter.upper()]
i=0
if complement==True:
patroon_list = list(patroon_str)
for char in patroon_str:
if char == '.':
patroon_list[i]='-'
elif char == '-': patroon_list[i]='.'
i+=1
patroon_str = ''.join(patroon_list)
if spiegel == True:
patroon_str = patroon_str[::-1]
return patroon_str
and here is the function in which it is called:
def groepen(woordenloc, morseloc):
morse_dict = morsecodes(morseloc)
woordpatroon_dict = {}
woorden = open(woordenloc, 'r')
for woord in woorden:
***woordpatroon_dict[woord] = patroon(woord, morse_dict)***
patroonwoorden_dict = {}
for woord, patroon in woordpatroon_dict.items():
if patroon in patroonwoorden_dict:
patroonwoorden_dict[patroon].add(woord)
else:
patroonwoorden_dict[patroon] = {woord}
return patroonwoorden_dict
where the stars are is where the error occurs
I'm new to python so I don't really know if this would be enough information.
this is my full code:
def morsecodes(locatie):
morse_file = open(locatie, 'r')
morse_dict = {}
for line_str in morse_file:
new_l = line_str.split()
if new_l[0].isalpha:
morse_dict[new_l[0].upper()] = new_l[1]
else: morse_dict[new_l[0]] = new_l[1]
return morse_dict
def patroon(woord, morse_dict, complement = False, spiegel = False):
patroon_str = ''
for letter in woord:
patroon_str += morse_dict[letter.upper()]
i=0
if complement==True:
patroon_list = list(patroon_str)
for char in patroon_str:
if char == '.':
patroon_list[i]='-'
elif char == '-': patroon_list[i]='.'
i+=1
patroon_str = ''.join(patroon_list)
if spiegel == True:
patroon_str = patroon_str[::-1]
return patroon_str
def isomorse(woord1, woord2, morse_dict, complement = False, spiegel = False):
patroon1 = patroon(woord1, morse_dict)
patroon2 = patroon(woord2, morse_dict, complement, spiegel)
if patroon1 == patroon2: return True
else: return False
def groepen(woordenloc, morseloc):
morse_dict = morsecodes(morseloc)
woordpatroon_dict = {}
woorden = open(woordenloc, 'r')
for woord in woorden:
woordpatroon_dict[woord] = patroon(woord, morse_dict)
patroonwoorden_dict = {}
for woord, patroon in woordpatroon_dict.items():
if patroon in patroonwoorden_dict:
patroonwoorden_dict[patroon].add(woord)
else:
patroonwoorden_dict[patroon] = {woord}
return patroonwoorden_dict
I have found my mistake, apparently python isn't (yet) smart enough to keep the name patroon as function and the 'patroon' as variable in my for loop separately (which I later use in the same function 'groepen')

Python 3 - How do I replace all letters in a sentence with their respective keys in a dictionary

So I'm creating a program that allows you to set each letter in the alphabet to another one using a dictionary. It then lets you input a sentence, which it then codes using the code you previously set. So far, I've completed (or I think I've completed) everything but the function that replaces the letters, because I have no idea what to do there. Any suggestions?
Here's the code:
import sys
def defineAlphabet():
alphabet = dict()
alphabet['a'] = input('a = ')
alphabet['b'] = input('b = ')
alphabet['c'] = input('c = ')
alphabet['d'] = input('d = ')
alphabet['e'] = input('e = ')
alphabet['f'] = input('f = ')
alphabet['g'] = input('g = ')
alphabet['h'] = input('h = ')
alphabet['i'] = input('i = ')
alphabet['j'] = input('j = ')
alphabet['k'] = input('k = ')
alphabet['l'] = input('l = ')
alphabet['m'] = input('m = ')
alphabet['n'] = input('n = ')
alphabet['o'] = input('o = ')
alphabet['p'] = input('p = ')
alphabet['q'] = input('q = ')
alphabet['r'] = input('r = ')
alphabet['s'] = input('s = ')
alphabet['t'] = input('t = ')
alphabet['u'] = input('u = ')
alphabet['v'] = input('v = ')
alphabet['w'] = input('w = ')
alphabet['x'] = input('x = ')
alphabet['y'] = input('y = ')
alphabet['z'] = input('z = ')
return alphabet
def codeSentence(sentence):
global translation
translation = 'WIP'
return translation
def menu():
print('''Would you like to:
a. Code a sentence
b. Set the code
c. Quit''')
userInput = input('//> ')
if userInput == 'a':
codeSentence(input('Enter Sentence: '))
print(translation)
menu()
if userInput == 'b':
defineAlphabet()
print('Defined!')
menu()
if userInput == 'c':
print('Goodbye!')
sys.exit(0)
else:
print('That is not an option.')
menu()
menu()
result = "some sentence".translate({ord(k): v for k, v in alphabet.items()})
See str.translate().

Resources