Python: Decrypting a file (have key) - python

I encrypted a file from ascii randomized key. I need to decrypt back into normal letters from and then put that into a new file
import random
lst = list(range(1,128)) #for key
numbersran = list()
while len(numbersran) < 128:
candidate = random.randint(1,128)
if candidate not in numbersran:
numbersran.append(candidate)
listsdict = dict(zip(lst,numbersran)) #makes key, changes every time
print("Encytption key=", listsdict)
print()
filename=input("Enter File: ")
with open(filename, "r") as file:
filetxt = file.read()
ascii_codes = [ord(c) for c in filetxt]
encrypted_codes = [listsdict[code] for code in ascii_codes]
print('\nEncrypted file: ',encrypted_codes)
cypher = "".join([chr(c) for c in encrypted_codes]) #encrypts from key
#decrypt below here into a file using the key to translate (should be original text from file)
I am not too sure how to reverse the process back to the original text in file. Must be decrypted back, can't just be copied from og file

The decryption process should be reverse of what has been done for encryption. Find below the code snippet.
decrypted_file = [ord(c) for c in cypher]
decrypted_key = list()
for value in decrypted_file:
for key in listsdict:
if listsdict[key] == value:
decrypted_key.append(key)
break
print(''.join([chr(c) for c in decrypted_key]))
There can be better ways to achieve the decryption but the solution in its naivest form should be like above.
easy way to replace this code snippet:
for value in decrypted_file:
for key in listsdict:
if listsdict[key] == value:
decrypted_key.append(key)
break
is to reverse listsdict keys with value as suggested by #scott hunter
decrypted_file = [ord(c) for c in cypher]
decrypted_key = list()
listsdict = dict(zip(numbersran,lst))
decrypted_key = [listsdict[code] for code in decrypted_file]
print(''.join([chr(c) for c in decrypted_key]))

Related

Encrypting a file into ascii key

I am trying to encrypt a file input by user into a randomized key of ascii. I got the random key and can translate the string in the file into ascii but cannot figure out how to translate it into the key
I tried many things but am not good enough in python to understand what else to try/ what I could be doing wrong
import random
lst = list(range(1,128)) #for key
numbersran = list()
while len(numbersran) < 128:
candidate = random.randint(1,128)
if candidate not in numbersran:
numbersran.append(candidate)
listsdict = dict(zip(lst,numbersran)) #makes the key
print("Encytption key=", listsdict)
print()
filename=input("Enter File: ")
file=open(filename, "r")
filetxt=file.readlines()
file.close() #for user input file
with open('file name here','r') as f: #also cant figure out how to make this work with user inputted file
for x in f:
arr=list(x)
ctd=list(map(str,map(ord,arr)))
filename=filename.replace('.txt','')
encrypt=open(filename,"w")
#below is for the encryption process
import random
lst = list(range(1,128)) #for key
# numbersran = list()
# while len(numbersran) < 128:
# candidate = random.randint(1,128)
# if candidate not in numbersran:
# numbersran.append(candidate)
random.shuffle(lst)
listsdict = dict(zip(lst, range(1,128))) #makes the key
print("Encytption key=", listsdict)
print()
filename=input("Enter File: ")
# file=open(filename, "r")
# filetxt=file.readlines()
# file.close()
with open(filename, "r") as file:
filetxt = file.read()
ascii_codes = [ord(c) for c in filetxt]
# with open('file name here','r') as f: #also cant figure out how to make this work with user inputted file
# for x in f:
# arr=list(x)
# ctd=list(map(str,map(ord,arr)))
# listdict is the key!
encrypted_codes = [listsdict[code] for code in ascii_codes]
print(encrypted_codes)
cypher = "".join([chr(c) for c in encrypted_codes])
print(cypher)
# filename=filename.replace('.txt','')
# encrypt=open(filename,"w")
#below is for the encryption process

how to create a program that will read an encrypted text from a file and will create a new file with the decrypted one

i would like to know how to create 2 things please:
• To write a program that will read an encrypted text from a file and will create a new file with the decrypted one.
• To create a dictionary base of the decryption page
my decryption page looks like this and it has to be a LIST '' a=z, b=y, c=x, d=w...''
this translation working good, but i need to read the encrypted string from an existing file, translate it and to write the decrypted string in a new file
Example code
# ------- DEFs------------
def encrypt(text):
encrypted_text = ""
alphabet = 'abcdefghijklmnopqrstuvwxyz'
for char in text:
if char in alphabet:
encrypted_text+= alphabet[25-alphabet.find(char)]
else:
encrypted_text+= char
return encrypted_text
# ------- MAIN ------------
# alphabet
inttab = 'abcdefghijklmnopqrstuvwxyz'
# inverted alphabet
outtab = 'zyxwvutsrqponmlkjihgfedcba'
print(inttab.find('a'))
# > 0
print(outtab.find('a'))
# > 25
# cipher -> inttab = outtab - 25
text = 'hello world!'
encrypted_text = encrypt(text)
print(encrypted_text)
# > svool dliow!
decrypted_text = encrypt(encrypted_text)
print(decrypted_text)
# > hello world!
You should create a Dictionary to find for each encrypted char entry its corresponding translation.
## Create an empty dictionary
your_dictionary = {}
## Fill your_dictionary with the (key, values) couples
## With keys your key list, and values your values list
for key, value in zip(keys, values):
your_dictionary[key] = value
## Decrypt your encrypted message
## With enc_message the encrypted message
decrypted_message = ""
for c in enc_message:
decrypted_message = decrypted_message+your_dictionary[c]
Now you may want to play it a little bit more secure, because you may face some issues if you try to decrypt either a char you havent added as a key in the dictionary, or a space.
decrypted_message = ""
for c in enc_message:
if c.isspace():
decrypted_message = decrypted_message + c
elif c not in your_dictionary :
## Handle this case how you want. By default you can add it.
decrypted_message = decrypted_message + c
else :
decrypted_message=decrypted_message + your_dictionary[c]
So, as you requested the encrypted and decrypted message should come from a file and should be outputted as a file, you can use the following functions and instruction to perform the whole cycle :
## Decrypt a message with a specific dictionary
def decrypt_message(message, your_dict):
decrypted_message = ""
word = ""
for index, c in enumerate(enc_message):
print(c)
if c.isspace():
decrypted_message = decrypted_message + c
elif c not in your_dict :
decrypted_message = decrypted_message + c
else :
decrypted_message = decrypted_message + your_dict[c]
return decrypted_message
## Populate a dictionary with the given couples
def populate_dictionary(keys, values):
your_dictionary = {}
for key, value in zip(keys, values):
your_dictionary[key] = value
return your_dictionary
## Example keys
keys = ['a', 'b', 'c']
## Example values
values = ['d', 'e', 'f']
## Open the input file
with open('encryptedMessage.txt', 'r') as file:
enc_message = file.read().replace('\n', '')
## Populating the dictionary
dic = populate_dictionary(keys, values)
## Decrypting the message
dec_message = decrypt_message(enc_message, dic)
## Creating and saving the decrypted message in the output file.
text_file = open("decryptedMessage.txt", "w")
text_file.write(dec_message)
text_file.close()

Many emoji characters are not read by python file read

I have a list of 1500 emoji character dictionary in a json file, and I wanted to import those to my python code, I did a file read and convert it to a python dictionary but now I have only 143 records. How can I import all the emoji to my code, this is my code.
import sys
import ast
file = open('emojidescription.json','r').read()
non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd)
emoji_dictionary = ast.literal_eval(file.translate(non_bmp_map))
#word = word.replaceAll(",", " ");
keys = list(emoji_dictionary["emojis"][0].keys())
values = list(emoji_dictionary["emojis"][0].values())
file_write = open('output.txt','a')
print(len(keys))
for i in range(len(keys)):
try:
content = 'word = word.replace("{0}", "{1}")'.format(keys[i],values[i][0])
except Exception as e:
content = 'word = word.replace("{0}", "{1}")'.format(keys[i],'')
#file.write()
#print(keys[i],values[i])
print(content)
file_write.close()
This is my input sample
{
"emojis": [
{
"👨‍🎓": ["Graduate"],
"©": ["Copy right"],
"®": ["Registered"],
"👨‍👩‍👧": ["family"],
"👩‍❤️‍💋‍👩": ["love"],
"™": ["trademark"],
"👨‍❤‍👨": ["love"],
"⌚": ["time"],
"⌛": ["wait"],
"⭐": ["star"],
"🐘": ["Elephant"],
"🐕": ["Cat"],
"🐜": ["ant"],
"🐔": ["cock"],
"🐓": ["cock"],
This is my result, and the 143 denotes number of emoji.
143
word = word.replace("�‍�‍�‍�", "family")
word = word.replace("Ⓜ", "")
word = word.replace("♥", "")
word = word.replace("♠", "")
word = word.replace("⌛", "wait")
I'm not sure why you're seeing only 143 records from an input of 1500 (your sample doesn't seem to display this behavior).
The setup doesn't seem to do anything useful, but what you're doing boils down to (simplified and skipping lots of details):
d = ..read json as python dict.
keys = d.keys()
values = d.values()
for i in range(len(keys)):
key = keys[i]
value = values[i]
and that should be completely correct. There are better ways to do this in Python, however, like using the zip function:
d = ..read json as python dict.
keys = d.keys()
values = d.values()
for key, value in zip(keys, values): # zip picks pair-wise elements
...
or simply asking the dict for its items:
for key, value in d.items():
...
The json module makes reading and writing json much simpler (and safer), and using the idiom from above the problem reduces to this:
import json
emojis = json.load(open('emoji.json', 'rb'))
with open('output.py', 'wb') as fp:
for k,v in emojis['emojis'][0].items():
val = u'word = word.replace("{0}", "{1}")\n'.format(k, v[0] if v else "")
fp.write(val.encode('u8'))
Why do you replace all emojis with 0xfffd in the lines:
non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd)
emoji_dictionary = ast.literal_eval(file.translate(non_bmp_map))
Just don't to this!
Using json:
import json
with open('emojidescription.json', encoding="utf8") as emojis:
emojis = json.load(emojis)
with open('output.txt','a', encoding="utf8") as output:
for emoji, text in emojis["emojis"][0].items():
text = "" if not text else text[0]
output.write('word = word.replace("{0}", "{1}")\n'.format(emoji, text))

how to read a specific line which starts in "#" from file in python

how can i read a specific line which starts in "#" from file in python and
set that line as a key in a dictionary (without the "#") and set all the lines after that line until the next "#" as a value is the dictionary
please help me
here is the file :
from collections import defaultdict
key = 'NOKEY'
d = defaultdict(list)
with open('thefile.txt', 'r') as f:
for line in f:
if line.startswith('#'):
key = line.replace('#', '')
continue
d[key].append(line)
Your dictionary will have a list of lines under each key. All lines that come before the first line starting with '#' would be stored under the key 'NOKEY'.
You could make use of Python's groupby function as follows:
from itertools import groupby
d = {}
key = ''
with open('input.txt', 'r') as f_input:
for k, g in groupby(f_input, key=lambda x: x[0] == '#'):
if k:
key = next(g).strip(' #\n')
else:
d[key] = ''.join(g)
print d
This would give you the following kind of output:
{'The Piper at the gates of dawn': '*Lucifer sam....\nsksdlkdfslkj\ndkdkfjoiupoeri\nlkdsjforinewonre\n', 'A Saucerful of Secrets': '*Let there be\nPeople heard him say'}
Tested using Python 2.7.9
A pretty simple version
filename = 'test'
results = {}
with open(filename, 'r') as f:
while (1):
text = f.readline()
if (text == ''):
break
elif (text[0] == "#"):
key = text
results[key] = ''
else:
results[key] += text
From (ignoring additional blank lines, a bi-product of the Answer formatting):
#The Piper at the gates of dawn
*Lucifer sam....
sksdlkdfslkj
dkdkfjoiupoeri
lkdsjforinewonre
# A Saucerful of Secrets
*Let there be
People heard him say
Produces:
{'#The Piper at the gates of dawn\n': '*Lucifer sam....\nsksdlkdfslkj\ndkdkfjoiupoeri\nlkdsjforinewonre\n', '# A Saucerful of Secrets \n': '*Let there be\nPeople heard him say\n'}

Use substitution cipher in python to encrypt and decrypt a .txt file and output to a new .txt file

I am able to open the rules file and create a dictionary to use for my encryption. I have to also create a dictionary to use for decrypting text. I assume it's basically the same function with minor changes. The encrypt works fine, but I can't get the decrypt to work. My second problem is that while I encrypted the file I took out all spaces and punctuation. I can't figure out how to get those back in the output file once I run the program. It just prints in a single column. Lastly I have to output this to a .txt file. I am able to create a .txt with a user assigned name, but can't get anything to print on the file.
Here is what I achieved so far.
#import clauses
import string
#function definitions
#encrypt dictionary
def createrulesdictencrypt(openFile):
rulesencrypt1 = {}
for line in openFile:
rulessplit = string.split(string.strip(line))
rulesencrypt1[rulessplit[0]] = rulessplit[1]
return rulesencrypt1
#decrypt dictionary
def createrulesdictdecrypt(openFile):
rulesdecrypt1 = {}
for line in openFile:
rulessplit = string.split(string.strip(line))
rulesdecrypt1[rulessplit[1]] = rulessplit[0]
return rulesdecrypt1
openFile = open('rules.txt', 'r')
rulesencrypt = createrulesdictencrypt(openFile)
rulesdecrypt = createrulesdictdecrypt(openFile)
#print rulesencrypt
#print rulesdecrypt
#function for encrypting file
def encryptfile(openFile2):
for line in openFile2:
for word in line.split():
empty = ''
for char in word:
if char not in string.punctuation:
char=char.lower()
empty = empty+char
if len(empty) == 2:
print rulesencrypt[empty]
empty = ''
if len(empty) == 1:
print rulesencrypt[empty]
#function for decrypting file
def decryptfile(openFile2):
for line in openFile2:
for word in line.split():
empty = ''
for char in word:
if char not in string.punctuation:
char=char.lower()
empty = empty+char
if len(empty) == 2:
print rulesdecrypt[empty]
empty = ''
if len(empty) == 1:
print rulesdecrypt[empty]
#main program
ende = raw_input("To encrypt a file, enter '0':\nTo decrypt a file, enter '1':")
filename = raw_input("Enter the name of the file to be processed:")
outfilename = raw_input("Enter the name of the file to save the result to:")
openFile2 = open(filename, 'r')
outputfile = open(outfilename, 'w')
fileencrypt = encryptfile(openFile2)
filedecrypt = decryptfile(openFile2)
if ende == "0":
print encryptfile(fileencrypt)
if ende == "1":
print decryptfile(filedecrypt)
This is what I am trying to encrypt
Sir Robin: "Oh, you liars!"
Minstrel: [singing] "Bravely taking to his feet, he beat a very brave
retreat. A brave retreat by brave Sir Robin."
Your first problem is that you're not actually writing your encrypted text to a file, instead you're just printing it to sys.stdout. Incidentally, print appends a \n to it's output by default.
You could rewrite your decrypt function as follows:
#function for decrypting file
def decryptfile(openFile2, outfile): # <- CHANGED to add outfile
for line in openFile2:
for word in line.split():
empty = ''
for char in word:
if char not in string.punctuation:
char=char.lower()
empty = empty+char
if len(empty) == 2:
outfile.write(rulesdecrypt[empty]) # <- CHANGED to write to file
empty = ''
if len(empty) == 1:
outfile.write(rulesdecrypt[empty]) # <- CHANGED to write to file
You will then need to invoke the decryptfile function with a file as its second argument. A similar change could be made to the encryptfile function.
With respect to punctuation and whitespace, either encrypt it or just leave it in place. Once you've removed it, there really isn't a good way to replace it.

Categories