White Spaces issue while converting to binary - python-3.x

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.

Related

how to fix ValueError: list index out of range

I keep getting this error:
line 23, in encode
raw_out[i][pos] = message[pos]
IndexError: list index out of range
for this part of the program:
def encode(message: str, key: int) -> str:
"""
Encode text using Rail-fence Cipher.
Replace all spaces with '_'.
:param message: Text to be encoded.
:param key: Encryption key.
:return: Decoded string.
"""
message = message.replace(" ", "_")
down = True
raw_out = []
out = ''
i = 0
for x in range(key):
raw_out.append({})
for pos in range(len(message)):
raw_out[i][pos] = message[pos]
if i == key - 1:
down = False
if i == 0:
down = True
if down:
i = i + 1
else:
i = i - 1
for p in raw_out:
for q in p:
out += p[q]
return out
I'm not sure how to fix the error. Any ideas?
When key is one or when the key is bigger than the length of the string return the string as it is. Doesn't make sense to do any processing.
right after the line
message = message.replace(" ", "_")
you can check for the condition
if key == 1 or key > len(message):
return message

Encryption algorithm randomly replaces some letters

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'

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...

Im trying to write to a file in a loop but it just seems to be writing nothing?

Here is the full code, it is for a basic random alphabetical shift encryption. For some reason, the .write() don't seem to be working.
from random import randint
import time
import os
sentence = input('What do you want to encrypt? ').lower()
namefile = input('What do you want to call the encrypted file? ')
alphabet = {'a':0,'b':1,'c':2,'d':3,'e':4,'f':5,'g':6,'h':7,'i':8,'j':9,'k':10,'l':11,'m':12,'n':13,'o':14,'p':15,'q':16,'r':17,'s':18,'t':19,'u':20,'v':21,'w':22,'x':23,'y':24,'x':25,' ':26,'.':27}
alphabet1 = {0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g',7:'h',8:'i',9:'j',10:'k',11:'l',12:'m',13:'n',14:'o',15:'p',16:'q',17:'r',18:'s',19:'t',20:'u',21:'v',22:'w',23:'x',24:'y',25:'x',26:' ',27:'.'}
shift = randint(1,27)
x = len(sentence)
y = 0
encrypted_file = open(namefile + '.txt', 'wt')
while y < x:
letter = sentence[y]
position = alphabet[letter]
position = position + shift
if position > 27:
position = position - 27
letter = alphabet1[position]
Here is the first .write(). This one is inside a loop.
encrypted_file.write(letter)
y = y + 1
This is the second .write(). This is a single use one
encrypted_file.write('\nEncryption Shift = ' + str(shift))
encrypted_file.close
time.sleep(2)
print('Done')
time.sleep(1)
print('Here is your encrypted file.')
time.sleep(2)
os.startfile('C:/Users/Jedidiah/Documents/' + namefile + '.txt')
The mode key "wt" doesn't exist.
check here! for all proper mode keys
UPDATE: try this
from random import randint
import time
import os
sentence = input('What do you want to encrypt? ').lower()
namefile = input('What do you want to call the encrypted file? ')
alphabet = {'a':0,'b':1,'c':2,'d':3,'e':4,'f':5,'g':6,'h':7,'i':8,'j':9,'k':10,'l':11,'m':12,'n':13,'o':14,'p':15,'q':16,'r':17,'s':18,'t':19,'u':20,'v':21,'w':22,'x':23,'y':24,'x':25,' ':26,'.':27}
alphabet1 = {0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g',7:'h',8:'i',9:'j',10:'k',11:'l',12:'m',13:'n',14:'o',15:'p',16:'q',17:'r',18:'s',19:'t',20:'u',21:'v',22:'w',23:'x',24:'y',25:'x',26:' ',27:'.'}
shift = randint(1,27)
x = len(sentence)
y = 0
encrypted_file = open(namefile + '.txt', 'a')
while y < x:
letter = sentence[y]
position = alphabet[letter]
position = position + shift
if position > 27:
position = position - 27
letter = alphabet1[position]
encrypted_file.write(letter)
y = y + 1
encrypted_file.write('\nEncryption Shift = ' + str(shift))
encrypted_file.close
time.sleep(2)
print('Done')
time.sleep(1)
print('Here is your encrypted file.')
time.sleep(2)
os.startfile('C:/Users/Jedidiah/Documents/' + namefile + '.txt')
if you want to overwrite the file use "w" for the mode key

Python 3.3 cypher script

So i have this code here in python 3.3, it cyphers text with the ceaser cypher.
What i need to know is how do i make a script that will convert it back from the original so that the person i send it too can read it.
message = input("Input: ")
key = 11
coded_message = ""
for ch in message:
code_val = ord(ch) + key
if ch.isalpha():
if code_val > ord('z'):
code_val -= ord('z') - ord('a')
coded_message = coded_message + chr(code_val)
else:
coded_message = coded_message + ch
# print ("Input: " + message)
print ("Output: " + coded_message)
One more thing, I plan to be putting this is a tkinter message box, with the two entry fields used for the input and output. one field should be used to type what i want to convert and the other should be used to show what the text looks like after it has been crypted. The button should start the encryption. here is the code:
import sys
from tkinter import *
def mHello():
mLabel = Label(mGui,text = input("Hello World"))
mLabel.grid(row=3, column=0,)
mGui = Tk()
ment = StringVar()
mGui.geometry("450x450+250+250")
mGui.title("My TKinter")
# input label
mLabel = Label(mGui,text = "Input",)
mLabel.grid(row=1,column=0,)
# output label
mLabeltwo = Label(mGui,text = "Input",)
mLabeltwo.grid(row=2,column=0,)
# convert button
mButton = Button(text = "Convert",command = mHello)
mButton.grid(row=3,column=0)
# input entry
mEntry = Entry(mGui,textvariable=ment)
mEntry.grid(row=1,column=1)
# output entry
mEntryTwo = Entry(mGui,textvariable=ment)
mEntryTwo.grid(row=2,column=1)
mGui.mainloop()
By the way i am only 15 and this is my 2nd day learning python.
Some credit goes to sources on this forum that have provided me with some code snippets
Thank-you in advance guys!
Before i say anything else you should be aware that minds much greater the mine have advised against writing your own cypher script for anything other then learning
If you want them to be able to decode your code then provide them with a key. so in your case:
s maps to h
t maps to i
f maps to t
I hope this code illustrates my suggestion:
In [1]: from cyro import your_cyrptic_function
In [2]: key = {'s':'h', 't':'i', 'f':'t'}
In [3]: secret_word = your_cyrptic_function('hit')
In [4]: decyrpted_secret_word = ''
In [5]: for letter in secret_word:
decyrpted_secret_word += key[letter]
...:
In [6]: print(decyrpted_secret_word)
hit
For the code above i turned your original code into a function:
def your_cyrptic_function(secret):
message = secret
key = 11
coded_message = ""
for ch in message:
code_val = ord(ch) + key
if ch.isalpha():
if code_val > ord('z'):
code_val -= ord('z') - ord('a')
coded_message = coded_message + chr(code_val)
else:
coded_message = coded_message + ch
# print ("Input: " + message)
return coded_message
there are several great ways to do this in python. If your interested in cyptopgraphy then check out Udacities class cs387 applied cryptography

Resources