I am making a client-server program implementing the Diffie-Hellman algorithm
Client:
from __future__ import print_function
import math
import socket
host = "localhost"
port = 1200
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
print("Connected with Server")
sharedPrime = 23 # p
sharedBase = 5 # g
aliceSecret = 6 # a
s.send(bytes(aliceSecret))
bobSecret=s.recv(1024)
# Alice Sends Bob A = g^a mod p
A = (sharedBase**aliceSecret) % sharedPrime
s.send(bytes(A))
B=s.recv(1024)
B=B.decode()
# Alice Computes Shared Secret: s = B^a mod p
aliceSharedSecret = (int(B)** aliceSecret) % sharedPrime
print( "Alice Shared Secret: ", aliceSharedSecret )
The server code is basically the same, except it handles "Bob's" side of the algorithm. My problem starts at this line:
aliceSharedSecret = (int(B)** aliceSecret) % sharedPrime
Which gives me this error:
invalid literal for int() with base 10: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
I've gone back to see what "B" actually is and it's just blank. What am I doing wrong?
Look at this line:
s.send(bytes(aliceSecret))
You convert int value to bytes here. This produces result like b'\x00\x00\x00\x00\x00\x00' that later cannot be directly casted to int even after decoding because it's not number in decimal form. There are 2 possible solutions:
1) Properly decode value, this line will interpret bytes object as int splitted into bytes:
B = int.from_bytes(B, byteorder='big', signed=False) # instead of B = B.decode()
2) Convert your original int value to str before converting to bytes so back convertation will work
Related
I have been trying to create a python bitcoin miner, that ACTUALLY puts the coins somewhere, so thats the first part of my quesiton, and the second part is how do I fix this error?
This is all of my code:
import hashlib
import time
max_nonce = 2 ** 32 # 4 billion
def proof_of_work(header, difficulty_bits):
# calculate the difficulty target
target = 2 ** (256-difficulty_bits)
for nonce in range(max_nonce):
hash_result = hashlib.sha256(str(header)+str(nonce)).hexdigest()
# check if this is a valid result, below the target
if int(hash_result, 16) < target:
print ("Success with nonce %d" % nonce)
print ("Hash is %s" % hash_result)
return (hash_result,nonce)
print ("Failed after %d (max_nonce) tries" % nonce)
return nonce
if __name__ == '__main__':
nonce = 0
hash_result = ''
# difficulty from 0 to 31 bits
for difficulty_bits in range(32):
difficulty = 2 ** difficulty_bits
print ("Difficulty: %ld (%d bits)" % (difficulty, difficulty_bits))
print ("Starting search...")
# checkpoint the current time
start_time = time.time()
# make a new block which includes the hash from the previous block
# we fake a block of transactions - just a string
new_block = 'test block with transactions' + hash_result
# find a valid nonce for the new block
(hash_result, nonce) = proof_of_work((new_block, difficulty_bits).hexdigest()
# checkpoint how long it took to find a result
end_time = time.time()
The line above this, The end_time seems to get an error, with no definition to what the error is. Please help.
Please note that I have tried a great deal of commenting out a bunch of things, changing code, and this is in python 3
I'm writing this as an answer because of the many issues.
First, hashllib requires byte strings. You would need
hash_result = hashlib.sha256((header+str(nonce)).encode('utf-8')).hexdigest()
Second, you're doing proof_of_work(...).hexdigest(), but that function isn't returning a hash object. You are already calling hexdigest. Your function either returns a 2-tuple, or a nonce. You want to remove the hexdigest call:
# find a valid nonce for the new block
(hash_result, nonce) = proof_of_work((new_block, difficulty_bits)
And, in the final line of proof_of_work change
return nonce
to
return (None, nonce)
Next, you are converting the nonce to decimal digits to tack it on to the block. That is completely wrong. The nonce needs to be a 4-byte value. Something like:
enonce = struct.pack('I', nonce)
hash_result = hashlib.sha256(header.encode('utf-8')+enonce).hexdigest()
Finally, this whole thing is silly. Have you timed that inner loop to see how long it takes? On my box, it takes about 500 microseconds per loop. To run that 4 billion times would require a month and a half. To repeat that for all 32 difficult values would make it take 4 years.
in attempt to make simple code to convert a hex string to base64:
my thought was: hex -> integer -> binary -> base64
so i wrote this little code:
import string
def bit(integer):
# To binary
return int(bin(integer))[2:]
#Hex multiply by 16 depending on position: 0xAB = A*(16**2) + B(16**1) = #10*16**2 + 11*16**1
#0x3a2f
#3*(16**2) + 7*(16**1) + 5
def removeletter(list):
#"abcdef" = "10 11 12 13 14 15"
for i, letter in enumerate(list):
if letter in hextable.keys():
list[i] = hextable[letter]
return list
def todecimal(h):
power = 0
l = [num for num in str(h)] #['3', 'a', '2', 'f']
l = removeletter(l)
l.reverse() #['f', '2', 'a', '3']
for i, n in enumerate(l):
number = int(n)
l[i] = number*(16**power)
power += 1
l.reverse()
return sum(l)
lowers = string.ascii_lowercase
hextable = {}
for number, letter in enumerate(lowers[:6]):
hextable[letter] = number + 10
in this little challenge i am doing, it says:
The string:
49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d
Should produce:
SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t
ok,
print(bit(todecimal('49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d')))
this should get the binary of the hex string, which if I put through a binary to base64 converter, should return SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t. or so i thought.
└─$ python3 hextobase64.py
10010010010011101101101001000000110101101101001011011000110110001101001011011100110011100100000011110010110111101110101011100100010000001100010011100100110000101101001011011100010000001101100011010010110101101100101001000000110000100100000011100000110111101101001011100110110111101101110011011110111010101110011001000000110110101110101011100110110100001110010011011110110111101101101
after checking using a hex to binary converter, i can see that the binary is correct.
now, if if i put this through a binary to base64 converter, it should return SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t, right?
the thing is, this binary to base64 converter gave me kk7aQNbS2NjS3M5A8t7q5EDE5MLS3EDY0tbKQMJA4N7S5t7c3urmQNrq5tDk3t7a which is odd to me. so I must be doing something wrong. from my understanding, hexadecimal can be represented in binary, and so can base64. base64 takes the binary and groups the binary by 6 digits to produce its own representation. so obviously if I have the binary, it should be interchangeable, but something is wrong.
what am i doing wrong?
So I have been stuck on this one for a while and could use some help. I have been trying to fix this code and I keep getting an error about invalid syntax. So here is the code I need help with need to convert from str or int to float.
# Input from the command line
import sys
A = sys.argv[1]
B = sys.argv[2]
C = sys.argv[3]
# Your code goes here
num = A * (B + C / 3)
# Outputs
print (float(num))
By default,python gets inputs from command line as str.So,you must convert them to floats before applying any operation
import sys
A=float(sys.argv[1])
B=float(sys.argv[2])
C=float(sys.argv[3])
.....
I taking input from user in python, How to know user has passed int or string or float etc??
number1 = eval(sys.argv[1])
number2 = eval(sys.argv[2])
if user passed input is float or int, i want to sum them, but how to know which type of data user passed? because all data which user passes is default type is string.
Python advocates the approach of "ask forgiveness, not permission". All user input is probably going to be a string - especially if you're getting it from sys.argv - but the best way to determine this is to attempt to make them numbers (using try/except) and then revert to different behavior if that fails.
num1str, num2str = sys.argv[1], sys.argv[2]
try:
# might as well do float, because every valid integer that can be represented in a
# string is also a valid float
num1 = float(num1str)
num2 = float(num2str)
num3 = num1 + num2
except ValueError:
# this happens if the variable cannot be converted, e.g. the user entered something
# that cannot be interpreted as a float
...
There are built in methods for that:
int()
str()
for example convert, if possible, while type() tells you what it is:
x = "Hi there"
print(type(x))
y = 3
print(type(y))
y = str(y)
print(type(y))
When receiving user input, you can try converting it and if successful, work with the result of the conversion:
_in = input("Some input please ")
try:
_in = int(_in)
except:
try:
_in = float(_in)
except:
pass
print(_in)
print(type(_in))
>>Some input please 3
>>3
>><class 'int'>
>>Some input please 3.5
>>3.5
>><class 'float'>
We can use eval() for that,
import sys
def main():
number1 = eval(sys.argv[1])
number2 = eval(sys.argv[2])
print(number1 + number2)
if __name__ == '__main__':
main()
when the user enters an integer as an input the input() function returns a string, but in the case of eval() it will evaluate the returned value from a string to an integer, same in float . No need to check data type every time.
see 3rd number of below link,
https://towardsdatascience.com/python-eval-built-in-function-601f87db191
I want to create a python script that uses strings in byte format that can be written to a file.
So the problem is something like this:
packed_int = struct.pack('>I', 1234)
result = packed_int + data
Here is the problem: In python 3 this will give an error because of concatenation between str and bytes.
So I solved the problem with the following code:
data = data.encode('utf-8')
packed_int = struct.pack('>I', 1234)
result = packed_int + data
Now if the data is already in bytes format this will give an error of not having an encode method. So I did this:
if type(data) is not bytes:
data = data.encode('utf-8')
The final problem is the fact that in python 2 the last snippet does not work.
How can I solve the problem without checking for python version?
You could use hasattr for duck typing:
if hasattr(data, 'encode'):
data = data.encode('utf-8')
Or you do something like this, which is what the six compatibility library does:
import sys
PY3 = sys.version_info[0] == 3
binary_type = (bytes if PY3 else str)
text_type = (str if PY3 else unicode)
# ...
if isinstance(data, text_type):
data = data.encode('utf-8')