I'm currently making an encryption program for an assignment however I cannot decrypt. The cause of this is that the key is a string made from a randomly generated bitstring however when turning the key back into a bitstring I get a different bitstring. I realized this after checking and finding out that the bitstring after turning the key back to binary is shorter than the bitstring used to make the key.
##imports##################################################
from socket import *
import random
##functions################################################
def CCipher(message, k):
output = ""
for x in message:
i = ord(x)
i = (i+k)%128
output += chr(i)
return output
def toBinary(message):
output = ""
for x in message:
i = bin(ord(x))[2:]
output += i
return output
def XOR(bitstring1, bitstring2):
output = ""
if(len(bitstring1) != len(bitstring2)):
print("Use bitstrings of the same length")
return None
for x in range(len(bitstring1)):
if(bitstring1[x] == "1" and bitstring2[x] == "0"):
output += "1"
elif(bitstring1[x] == "0" and bitstring2[x] == "1"):
output += "1"
else:
output += "0"
return output
def randomBinary(k):
output = ""
for x in range(k):
i = random.randint(0,1)
output = output + str(i)
return output
def toString(message):
output = ""
i = ""
n = 0
for x in message:
n += 1
i += x
if(n == 7):
output += chr(int(i,2))
n = 0
i = ""
return output
##server stuff#########################################
serverName = "OmariPC"
serverPort = 12347
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
##files################################################
nowar = open("NoWar.dat",'r')
trump = open("Trump.dat","w")
##encryption###########################################
message = nowar.read()
mesBin = toBinary(message)
bkey = randomBinary(len(mesBin))
encrypted = XOR(mesBin, bkey)
encrypted = toString(encrypted)
key = toString(bkey)
trump.write(encrypted)
trump.close()
enKey = CCipher(key, 4)
##sending###############################################
clientSocket.send(enKey.encode())
print(len(enKey))
clientSocket.send(encrypted.encode())
print(len(encrypted))
##testing###############################################
if key == toString(bkey):
print(True)
else:
print(False)
if len(toBinary(key)) == len(bkey):
print(True)
else:
print(False)
output:
168
168
True
False
def toBinary(message):
output = ""
for x in message:
i = bin(ord(x))[2:]
output += i
return output
bin(ord(x)) generates strings of variable length. For example:
>>> bin(ord(' '))
0b100000
>>> bin(ord('a'))
0b1100001
You concatenate all of the results of bin() together, so there's no way to separate them later. Meanwhile, your toString() function reads exactly 7 "bits" at a time.
You could make bin() append chunks of a fixed-size instead:
# Pad the left with 0s to always generate a string of length 7.
# (Assumes that all input characters are ASCII.)
assert(ord(x) < 128)
bin(ord(x))[2:].rjust(7, '0')
Related
I'm creating a calculator and here's part of the code:
def _digit_formatting(x):
numbers = '1234567890.'
start_idxs = []
end_idxs = []
is_start = True
try:
for idx, value in enumerate(x):
if value in numbers and is_start:
start_idxs.append(idx)
is_start = False
elif value in numbers and idx == len(x) - 1:
end_idxs.append(len(x) - 1)
elif value in numbers and not is_start:
pass
elif value not in numbers and len(start_idxs) > len(end_idxs):
end_idxs.append(idx-1)
is_start = True
except:
...
if len(start_idxs) > len(end_idxs):
end_idxs.append(start_idxs[-1])
start_idxs.reverse()
end_idxs.reverse()
x = list(x)
for idx in range(len(start_idxs)):
if start_idxs[idx] == end_idxs[idx]:
num = x[start_idxs[idx]:end_idxs[idx]+1]
else:
num = x[start_idxs[idx]:end_idxs[idx]+1]
num = ''.join(num)
x = ''.join(x)
x = x[::-1]
num = num[::-1]
x = x.replace(num, '', 1)
x = list(x)
x.reverse()
num = num[::-1]
temp = f'{int(num):,}'
x.insert(start_idxs[idx], temp)
x = ''.join(x)
return x
def calculate(sv):
# This function is called when there's changes in entry box
if self.input_string_var.get() == '':
self.result_string_var.set('')
# Start
real_result = self.input_string_var.get().replace(',', '')
percent_count = self.input_string_var.get().count('%')
# Formatting input string
x = _digit_formatting(real_result)
print(x)
self.input_string_var.set(x)
if percent_count != 0:
numbers = '0123456789.'
for cnt in range(percent_count):
percent_idx = real_result.find('%', 0)
limit_operator = 2
percent_number = ''
for i in range(percent_idx - 1, -1, -1):
if real_result[i] not in numbers:
limit_operator -= 1
if limit_operator == 0:
break
if limit_operator == 1:
if real_result[i] in '*/':
percent_number = ''
break
else:
percent_number += real_result[i]
if percent_number == '':
percent_number = '1'
else:
percent_number = percent_number[1:][::-1]
real_result = list(real_result)
real_result[percent_idx] = f'/100*{percent_number}'
real_result = ''.join(real_result)
else:
real_result = self.input_string_var.get().replace(',', '')
try:
if eval(real_result) == int(eval(real_result)):
self.result_string_var.set(f'{int(eval(real_result)):,}')
else:
self.result_string_var.set(f'{int(eval(real_result)):,}')
except:
None
if self.input_string_var.get() == '':
self.result_string_var.set('')
# Entry box string variable
self.input_string_var = tk.StringVar()
self.input_string_var.trace('w', lambda name, index, mode: calculate(self.input_string_var))
There is two functions, first is _digit_formatting which is to format the equation to put comma like thousands, million and billion. The calculate function is called every time there's changes on the input string variable. But when I try to set the string variable to equation after formatting there seems to be a mistake, but if I print the value, it is correct. Example if I enter 1200 the value I printed is 1,200 which is correct but the value on the text box is not correct. Sorry if the code is messy, I'm still learning to make a clean code.
I cannot reproduce your code.
If you can take a look of my example.
n = 1234567890
print(f"I have {n:,} Reputations")
Result:
I have 1,234,567,890 Reputations
This is a script that is a simple proof of work and it's in md5 algo. Is there any way I can use it to transfer it to sha256?
# proof-of-work.py
import md5
string = "1"
complete = False
n = 0
while complete == False:
curr_string = string + str(n)
curr_hash = md5.new(curr_string).hexdigest()
n = n + 1
# slows performance drastically
## print curr_hash
if curr_hash.startswith('000000'):
print curr_hash
print curr_string
complete = True
from hashlib import sha256
string = "1"
complete = False
n = 0
while complete == False:
curr_string = string + str(n)
curr_hash = sha256(curr_string.encode()).hexdigest()
n = n + 1
print(curr_hash + ' ' + curr_hash[:4])
This outputs hashes and first 4 bytes like this:
c19df416e581278d028f20527b96c018f313e983f0a9bda4914679bb482d14f6 c19d
b5662892a57d57b6d904fa6243fae838c28aaebc190fc885ee2e20de6fbcaddb b566
a9c0a662c81abe40bca7d250e93965285e0aea74f2f3edde704015c11e98cdeb a9c0
635f19669b8b48cd78f05bfe52ccf4bfbdb55e544486d71404f5fa786d93e5be 635f
and never ends. Add your logic to exit the loop.
i have a question.
i don't know why my code is wrong
def binary_converter(decimal_number):
i = decimal_number
result = ''
while i >= 0 :
if i % 2 == 0:
result = result + "0"
i = i/2
else :
result = "1"
i = i/2
return result.strip()
it is my code. what is wrong?
There were few little mistakes in your code, olease refer to comments below for details:
def binary_converter(decimal_number):
if decimal_number==0: #corner case
return "0";
i = decimal_number
result = ""
while i>0: # while i >= 0 : //your loop was running indefinitely
if i % 2 == 0:
result = result + "0"
i = i//2 # i= i/2 was doing exact division for eg. 3/2=1.5 but 3//2=1
else :
result = result + "1" # there was a silly mistake here
i = i//2
return result[::-1].strip() # ans should be reversed before converting to integer
I have the following code that is self explanatory in the docstring. How do I get it to not flag single letters with a 1, thereby turning a single digit into 2 in the final compressed string?
For example in the docstring it turns AAABBBBCDDDD -> A3B4C1D4 but I want it to turn into A3B4CD4. I'm new at this so it's any comments are greatly appreciated.
class StringCompression(object):
'''
Run Length Compression Algorithm: Given a string of letters, such as
nucleotide sequences, compress it using numbers to flag contiguous repeats.
Ex: AAABBBBCDDDD -> A3B4C1D4
>>>x = StringCompression('AAAAbC')
>>>x.compress()
'A4bC'
'''
def __init__(self, string):
self.string = string
def compress(self):
'''Executes compression on the object.'''
run = ''
length = len(self.string)
if length == 0:
return ''
if length == 1:
return self.string #+ '1'
last = self.string[0]
count = 1
i = 1
while i < length:
if self.string[i] == self.string[i - 1]:
count += 1
else:
run = run + self.string[i - 1] + str(count)
count = 1
i += 1
run = (run + self.string[i - 1] + str(count))
return run
Here's an alternative solution using itertools.groupby and a generator:
from itertools import chain, groupby
x = 'AAABBBBCDDDD'
def compressor(s):
for i, j in groupby(s):
size = len(list(j))
yield (i, '' if size==1 else str(size))
res = ''.join(chain.from_iterable(compressor(x)))
print(res)
A3B4CD4
Now it works the way I wanted it to. Thanks!
class StringCompression(object):
'''
Run Length Compression Algorithm: Given a string of letters, such as
nucleotide sequences, compress it using numbers to flag contiguous repeats.
Ex: AAABBBBCDDDD -> A3B4CD4
Notice that single letter do not get a 1 flag to prevent expansion.
>>>x = StringCompression('AAAAbC')
>>>x.compress()
'A4bC'
'''
def __init__(self, string):
self.string = string
def compress(self):
'''Executes compression on the object.'''
run = ''
length = len(self.string)
if length == 0:
return ''
if length == 1:
return self.string #+ '1'
last = self.string[0]
count = 1
i = 1
while i < length:
if self.string[i] == self.string[i - 1]:
count += 1
else:
run = run + self.string[i - 1] + str(count)
count = 1
i += 1
run = (run + self.string[i - 1] + str(count))
compressed_string = ''
for i in run:
if i != '1':
compressed_string += i
return compressed_string
I have the following code which helps to bruteforce hashes
The first if statement will run, the values are hash=wordlist.txt, args=abtfg, values=[0, "0,1", 0, wordlist.txt, true]
def bruteforce(hash, args, values):
if "." in hash:
files = open(values[args.find("f")]) # Open wordlist.txt
for xhsd in files.readlines():
hash = xhsd
alphabet = "abcdefghijklmnopqrstuvwxyz"
alphabet += alphabet.upper() + "0123456789!$%^&*(){}~#][;:'#/?.>,<"
if "b" in args: # It is
m = args.find("b")
m = values[m]
else:
m = "0,16"
# m is 0,10
start_time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
l = 0
print("Cracking...")
attempts = 0
while l == 0:
password = ""
for x in range(random.randrange(int(m.split(",")[0])+1,int(m.split(",")[1])+1)): # range(random.randrange(0,10))
password += alphabet[random.randrange(0,len(alphabet)-1)]
num = hash_types[int(values[args.find("t")])] # num="md5"
htype = "hash2 = hashlib."+num+"(password).hexdigest()"
exec(htype) # hash2 = md5(password)
print hash2 + ":" + hash # Compares the hashes
if hash == hash2:
print password
l = 1
else:
print "Trying..."
The first item it tries, it cracks it almost instantly, printing:
0cc175b9c0f1b6a831c399e269772661:0cc175b9c0f1b6a831c399e269772661
(this is hash2 and hash). So we now know these two variables are equal. However, the if statement directly below it, doesn't run. This is the weirdest thing I've seen in Python, could anyone explain why this is? I've printed both variables and they're clearly the same...
Removing whitespace could help:
if hash.strip() == hash2.strip():