I'm currently writing an ascii-binary/binary-ascii converter in Python for a school project, and I have an issue with converting from ascii (String text) to binary. The idea is to print the outcome in the test() on the bottom of the code.
When running the code in WingIDE, an error occurs:
On the line starting with
bnary = bnary + binary[chnk]
KeyError: "Norway stun Poland 30:28 and spoil Bielecki's birthday party."
What I'm trying to do here is to convert the String of text stored in "text.txt" to a String of integers, and then print this binary string.
Any help is greatly appreciated. I tried looking at other ascii-binary vice-versa convertion related questions, but none seemed to work for me.
My code:
def code():
binary = {}
ascii = {}
# Generate ascii code
for i in range(0,128) :
ascii[format(i,'08b')] = chr(i)
# Reverse the ascii code, this will be binary
for k, v in ascii.iteritems():
binary[v] = binary.get(v, [])
binary[v].append(k)
return ascii
def encode(text,binary):
'''
Encode some text using text from a source
'''
bnary = ""
fi = open(text, mode='rb')
while True:
chnk = fi.read()
if chnk == '':
break
if chnk != '\n':
binry = ""
bnary = bnary + binary[chnk]
return bnary
def decode(sourcecode,n, ascii):
'''
Decode a sourcecode using chunks of size n
'''
sentence = ""
f = open(sourcecode, mode='rb') # Open a file with filename <sourcecode>
while True:
chunk = f.read(n) # Read n characters at time from an open file
if chunk == '': # This is one way to check for the End Of File in Python
break
if chunk != '\n':
setence = "" # The ascii sentence generated
# create a sentence
sentence = sentence + ascii[chunk]
return sentence
def test():
'''
A placeholder for some test cases.
It is recommended that you use some existing framework, like unittest,
but for a temporary testing in a development version can be done
directly in the module.
'''
print encode('text.txt', code())
print decode('sourcecode.txt', 8, code())
test()
If you want to decode and encode, have this solutions
Encode ascii to bin
def toBinary(string):
return "".join([format(ord(char),'#010b')[2:] for char in string])
Encode bin to ascii
def toString(binaryString):
return "".join([chr(int(binaryString[i:i+8],2)) for i in range(0,len(binaryString),8)])
fi.read() returns the whole document the first time and '' next times. So you should do
text = fi.read()
for char in text:
do_stuff()
Edit1
You can only read your file once. Thus you have to get your chars one by one. A file.read returns a string containing the whole document.
You can iterate over a string to get chars one by one.
The main error is your binary is {"a":['010001110'], "b":...} and you try to access with the key "azerty" where you should do it char by char:
string = "azer"
result = []
for c in string:
result += binary[c]
>>> result = [['11001'],[1001101'],...]
# Lets say your filename is stored in fname
def binary(n):
return '{0:08b}'.format(n)
with open(fname) as f:
content = f.readlines()
for i in content:
print(binary(ord(i)), end='')
print('')
This will give you the integer value(from ascii) of each character in the file, line by line
Related
i want to replace a set of characters from a text file when i give a work with blanks in it like for example :
i gave the line The Language Is _th_n !
it should return python replacing _ with text from a file like text.txt
i wrote this code please check once
with open('data/text','r', encoding='utf8') as file:
word_list = file.read()
def solve(message):
hint = []
for i in range(15,len(message) - 1):
if message[i] != '\\':
hint.append(message[i])
hint_string = ''
for i in hint:
hint_string += i
hint_replaced = hint_string.replace('_', '!')
solution = re.findall('^'+hint_replaced+'$', word_list, re.MULTILINE)
return solution```
I am trying to use the replace function to take items from a list and replace the fields below with their corresponding values, but no matter what I do, it only seems to work when it reaches the end of the range (on it's last possible value of i, it successfully replaces a substring, but before that it does not)
for i in range(len(fieldNameList)):
foo = fieldNameList[i]
bar = fieldValueList[i]
msg = msg.replace(foo, bar)
print msg
This is what I get after running that code
<<name>> <<color>> <<age>>
<<name>> <<color>> <<age>>
<<name>> <<color>> 18
I've been stuck on this for way too long. Any advice would be greatly appreciated. Thanks :)
Full code:
def writeDocument():
msgFile = raw_input("Name of file you would like to create or write to?: ")
msgFile = open(msgFile, 'w+')
msg = raw_input("\nType your message here. Indicate replaceable fields by surrounding them with \'<<>>\' Do not use spaces inside your fieldnames.\n\nYou can also create your fieldname list here. Write your first fieldname surrounded by <<>> followed by the value you'd like to assign, then repeat, separating everything by one space. Example: \"<<name>> ryan <<color>> blue\"\n\n")
msg = msg.replace(' ', '\n')
msgFile.write(msg)
msgFile.close()
print "\nDocument written successfully.\n"
def fillDocument():
msgFile = raw_input("Name of file containing the message you'd like to fill?: ")
fieldFile = raw_input("Name of file containing the fieldname list?: ")
msgFile = open(msgFile, 'r+')
fieldFile = open(fieldFile, 'r')
fieldNameList = []
fieldValueList = []
fieldLine = fieldFile.readline()
while fieldLine != '':
fieldNameList.append(fieldLine)
fieldLine = fieldFile.readline()
fieldValueList.append(fieldLine)
fieldLine = fieldFile.readline()
print fieldNameList[0]
print fieldValueList[0]
print fieldNameList[1]
print fieldValueList[1]
msg = msgFile.readline()
for i in range(len(fieldNameList)):
foo = fieldNameList[i]
bar = fieldValueList[i]
msg = msg.replace(foo, bar)
print msg
msgFile.close()
fieldFile.close()
###Program Starts#####--------------------
while True==True:
objective = input("What would you like to do?\n1. Create a new document\n2. Fill in a document with fieldnames\n")
if objective == 1:
writeDocument()
elif objective == 2:
fillDocument()
else:
print "That's not a valid choice."
Message file:
<<name>> <<color>> <<age>>
Fieldname file:
<<name>>
ryan
<<color>>
blue
<<age>>
18
Cause:
This is because all lines except the last line read from the "Fieldname" file contains "\n" characters. So when the program comes to the replacing part fieldNameList , fieldValueList and msg looks like this:
fieldNameList = ['<<name>>\n', '<<color>>\n', '<<age>>\n']
fieldValueList = ['ryan\n', 'blue\n', '18']
msg = '<<name>> <<color>> <<age>>\n'
so the replace() function actually searches for '<<name>>\n','<<color>>\n','<<age>>\n' in msg string and only <<age>> field get replaced.(You must have a "\n" at the end of msg file, otherwise it won't be replaced as well).
Solution:
use rstrip() method when reading lines to strip the newline character at the end.
fieldLine = fieldFile.readline().rstrip()
I have a program that decodes a caesar cipher and a few text files with multiple lines to decode.
There is always a blank line after the text according to my lecturers code checker, but I don't see anything when I run the code myself.
Removing the last character only removes the last letter or number in the text and not the newline.
Here's my code:
import sys
import string
import collections
ciphertext_lines = sys.stdin.readlines()
ciphertext = ''
for i in ciphertext_lines:
ciphertext += i
alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
def getShiftVal():
string = ''
for line in ciphertext:
string = string + line
most_common_letter = ((collections.Counter(string).most_common(2)[1])[0])
shift_val = (alphanum.index(most_common_letter) - 4)
return shift_val
def decrypt(ciphertext, n):
alphabet_numbers = collections.deque(string.ascii_uppercase + string.digits)
alphanum = ''.join(list(alphabet_numbers))
alphabet_numbers.rotate(n)
alphanum_rotated = ''.join(list(alphabet_numbers))
return ciphertext.translate(str.maketrans(alphanum, alphanum_rotated))
def main():
n = getShiftVal()
decrypted = decrypt(ciphertext, n)
print(decrypted)
if __name__ == '__main__':
main()
print by default adds a newline after its output. Under Python 2, use print decrypted, (note the trailing comma) to suppress the trailing newline. Under Python 3, use print(decrypted, end=''). Or, alternatively, you can just use sys.stdout.write(decrypted) to write the output without any formatting.
I am (attempting) to write a program that searches through a hex file for instances of a hex string between two values, eg. Between D4135B and D414AC, incrementing between the first value until the second is reached- D4135B, D4135C, D4135D etc etc.
I have managed to get it to increment etc, but it’s the search part I am having trouble with.
This is the code I have so far, it's been cobbled together from other places and I need to make it somehow output all search hits into the output file (file_out)
I have exceeded the limit of my Python understanding and I'm sure there's probably a much easier way of doing this. I would be very grateful for any help.
def search_process(hx): # searching for two binary strings
global FLAG
while threeByteHexPlusOne != threeByteHex2: #Keep incrementing until second value reached
If Flag:
if hx.find(threeByteHex2) != -1:
FLAG = False #If threeByteHex = ThreeByteHexPlusOne, end search
Print (“Reached the end of the search”,hx.find(threeByteHexPlusOne))
Else:
If hx.find(threeByteHexPlusOne) != -1:
FLAG = True
Return -1 #If no results found
if __name__ == '__main__':
try:
file_in = open(FILE_IN, "r") #opening input file
file_out = open(FILE_OUT, 'w') #opening output file
hx_read = file_in.read #read from input file
tmp = ''
found = ''
while hx_read: #reading from file till file is empty
hx_read = tmp + hx_read
pos = search_process(hx_read)
while pos != -1:
hex_read = hx_read[pos:]
if FLAG:
found = found + hx_read
pos = search_process(hx_read)
tmp = bytes_read[]
hx_read = file_in.read
file_out.write(found) #writing to output file
except IOError:
print('FILE NOT FOUND!!! Check your filename or directory/PATH')
Here's a program that looks through a hex string from a file 3 bytes at a time and if the 3-byte hex string is between the given hex bounds, it writes it to another file. It makes use of generators to make getting the bytes from the hex string a little cleaner.
import base64
import sys
_usage_string = 'Usage: python {} <input_file> <output_file>'.format(sys.argv[0])
def _to_base_10_int(value):
return int(value, 16)
def get_bytes(hex_str):
# Two characters equals one byte
for i in range(0, len(hex_str), 2):
yield hex_str[i:i+2]
def get_three_byte_hexes(hex_str):
bytes = get_bytes(hex_str)
while True:
try:
three_byte_hex = next(bytes) + next(bytes) + next(bytes)
except StopIteration:
break
yield three_byte_hex
def find_hexes_in_range(hex_str, lower_bound_hex, upper_bound_hex):
lower_bound = _to_base_10_int(lower_bound_hex)
upper_bound = _to_base_10_int(upper_bound_hex)
found = []
for three_byte_hex in get_three_byte_hexes(hex_str):
hex_value = _to_base_10_int(three_byte_hex)
if lower_bound <= hex_value < upper_bound:
found.append(three_byte_hex)
return found
if __name__ == "__main__":
try:
assert(len(sys.argv) == 3)
except AssertionError:
print _usage_string
sys.exit(2)
file_contents = open(sys.argv[1], 'rb').read()
hex_str = base64.decodestring(file_contents).encode('hex')
found = find_hexes_in_range(hex_str, 'D4135B', 'D414AC')
print('Found:')
print(found)
if found:
with open(sys.argv[2], 'wb') as fout:
for _hex in found:
fout.write(_hex)
Check out some more info on generators here
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.