python cannot struct.pack struct.error: cannot convert argument to integer - python

I read from a hex file that's 1444352kB of size. I take 128 bytes of data and try to pack them using python struct.pack.
Below is the code :
#!/usr/bin/env python
import os
import struct
import ctypes
import array
import binascii
import sys,getopt
filename = file_location
blocksize = 1444352
opts,args = getopt.getopt(sys.argv[1:],'f:b:')
for o,a in opts:
if o == '-f':
filename = a
if o == '-b':
blocksize = a
offset = 0
with open(filename,"rb") as f:
block = f.read(blocksize)
str = ""
for ch in block:
str += hex(ord(ch))+" "
sector = []
c = 0
for s in str.split(' ') :
sector.append(s)
c += 1
if c == 128 :
sector.append("")
c = 0
#print sector
sector = ', '.join(sector)
#print sector
print type(sector)
sector = sector.split(',')
secdata = []
for items in sector[0:127] :
secdata.append(items)
secdata2 = ','.join(secdata)
print secdata2
print type(secdata2)
struct.pack('B', secdata2)
break
The secdata that appears to be a list, I have converted to string. but I always get error struct.error: cannot convert argument to integer when I try to pack the 128 bytes of data.

Related

How to implement HMAC in python without using the hmac library?

I want to implement the hmac algorithm with SHA-1 by the definition from RFC 2104. The code is running but the results aren't the same as the test-vectors from RFC. I'm not sure if I'm loading the values correctly(String to Hex, or String to Bytes?).
As template I've used the pseudo-code from wikipedia
I'm not sure about the terms 'blocksize' and 'output size'. In the code from wikipedia the outputsize is one of the input values but never used.
This is my code so far:
First I'm setting up a hash-function, then I'm converting my input-strings (key and message) into hex values. Next step is to to look if key hast go get hashed or filled with zeros. Next I'm xor-ing the single chars from the key with those values (I don't know where they come from, but they're in every example without any comment). Last but not least I'm combining an inner string(I_key_pad + message) and hash it which results in an outer strings that im combining with the outer pad and hash it again.
import hashlib
from functools import reduce
def hmac(key, message, hashfunc):
hasher = hashlib.sha1
blocksize = 40
message = toHex(message) #is this right?
key = toHex(key)
#alternative: loading values as bytes
#message = bytes(message, 'utf-8')
#key = bytes(key, 'utf-8')
if len(key) > blocksize:
key = hasher(key)
else:
#key = key.ljust(blocksize, '0') #filling from right to left
#key = key.ljust(blocksize, b'\0') #same as above but for bytes
key = pad(key, blocksize) #filling from left to right
val1 = 0x5c
val2 = 0x36
i = 0
o_key_pad = ""
i_key_pad = ""
while i < blocksize:
o_key_pad += str(ord(key[i]) ^ val1)
i_key_pad += str(ord(key[i]) ^ val2)
i += 1
tmp_string = str(i_key_pad) + str(message)
tmp_string = tmp_string.encode()
inner_hash = hasher(tmp_string).hexdigest()
fullstring = str(o_key_pad) + inner_hash
fullstring = fullstring.encode()
fullstring = hasher(fullstring).hexdigest()
print(fullstring)
def pad(key, blocksize):
key = str(key)
while len(key) < blocksize:
key = '0' + key
key = key
return key
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0' + hv
lst.append(hv)
return reduce(lambda x, y: x + y, lst)
def main():
while (1):
key = input("key = ")
message = input("message = ")
hash = input("hash (0: SHA-256, 1: SHA-1) = ")
hmac(key, message, hash)
if __name__ == "__main__":
main()
I'm not understanding all the steps in your code, but here's a short example showing HMAC-SHA1 using only hashlib.sha1, with a helper function xor.
import hashlib
def xor(x, y):
return bytes(x[i] ^ y[i] for i in range(min(len(x), len(y))))
def hmac_sha1(key_K, data):
if len(key_K) > 64:
raise ValueError('The key must be <= 64 bytes in length')
padded_K = key_K + b'\x00' * (64 - len(key_K))
ipad = b'\x36' * 64
opad = b'\x5c' * 64
h_inner = hashlib.sha1(xor(padded_K, ipad))
h_inner.update(data)
h_outer = hashlib.sha1(xor(padded_K, opad))
h_outer.update(h_inner.digest())
return h_outer.digest()
def do_tests():
# test 1
k = b'\x0b' * 20
data = b"Hi There"
result = hmac_sha1(k, data)
print(result.hex())
# add tests as desired

SHA256 doesn't yield same result

I'm following on this tutorial and in part 2 (picture below) it shows that the SHA256 yields a result different than what I get when I ran my python code:
the string is: 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
While the tutorial SHA256 comes to: 600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408
My short python shows:
sha_result = sha256(bitconin_addresss).hexdigest().upper()
print sha_result
32511E82D56DCEA68EB774094E25BAB0F8BDD9BC1ECA1CEEDA38C7A43ACEDDCE
in fact, any online sha256 shows the same python result; so am I missing here something?
You're hashing the string when you're supposed to be hashing the bytes represented by that string.
>>> hashlib.sha256('0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'.decode('hex')).hexdigest().upper()
'600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408'
You could use Gavin's "base58.py", which I believe he no longer shares it on his github page. However you probably could easily google and find different versions of it from github.
Here is one version edited a little by me:
#!/usr/bin/env python
"""encode/decode base58 in the same way that Bitcoin does"""
import math
import sys
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars)
def b58encode(v):
""" encode v, which is a string of bytes, to base58.
"""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += ord(c) << (8*i) # 2x speedup vs. exponentiation
result = ''
while long_value >= __b58base:
div, mod = divmod(long_value, __b58base)
result = __b58chars[mod] + result
long_value = div
result = __b58chars[long_value] + result
# Bitcoin does a little leading-zero-compression:
# leading 0-bytes in the input become leading-1s
nPad = 0
for c in v:
if c == '\0': nPad += 1
else: break
return (__b58chars[0]*nPad) + result
def b58decode(v):
""" decode v into a string of len bytes
"""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += __b58chars.find(c) * (__b58base**i)
result = ''
while long_value >= 256:
div, mod = divmod(long_value, 256)
result = chr(mod) + result
long_value = div
result = chr(long_value) + result
nPad = 0
for c in v:
if c == __b58chars[0]: nPad += 1
else: break
result = chr(0)*nPad + result
return result
try:
import hashlib
hashlib.new('ripemd160')
have_crypto = True
except ImportError:
have_crypto = False
def hash_160(public_key):
if not have_crypto:
return ''
h1 = hashlib.sha256(public_key).digest()
r160 = hashlib.new('ripemd160')
r160.update(h1)
h2 = r160.digest()
return h2
def hash_160_to_bc_address(h160, version="\x00"):
if not have_crypto:
return ''
vh160 = version+h160
h3=hashlib.sha256(hashlib.sha256(vh160).digest()).digest()
addr=vh160+h3[0:4]
return b58encode(addr)
def public_key_to_bc_address(public_key, version="\x00"):
if not have_crypto or public_key is None:
return ''
h160 = hash_160(public_key)
return hash_160_to_bc_address(h160, version=version)
def sec_to_bc_key(sec, version="\x80"):
if not have_crypto or sec is None:
return ''
vsec = version+sec +"\x01"
hvsec=hashlib.sha256(hashlib.sha256(vsec).digest()).digest()
return b58encode(vsec+hvsec[0:4])
def bc_key_to_sec(prv):
return b58decode(prv)[1:33]
def bc_address_to_hash_160(addr):
bytes = b58decode(addr)
return bytes[1:21]
if __name__ == '__main__':
if len(sys.argv) > 1:
if sys.argv[1] == '-en':
print b58encode(sys.argv[2].decode('hex_codec'))
if sys.argv[1] == '-de':
print b58decode(sys.argv[2]).encode('hex_codec')
if sys.argv[1] == '-pub':
print public_key_to_bc_address(sys.argv[2].decode('hex_codec'))
if sys.argv[1] == '-adr':
print bc_address_to_hash_160(sys.argv[2]).encode('hex_codec')
if sys.argv[1] == '-sec':
print sec_to_bc_key(sys.argv[2].decode('hex_codec'))
if sys.argv[1] == '-prv':
print bc_key_to_sec(sys.argv[2]).encode('hex_codec')
else:
print ''
print 'Usage: ./base58.py [options]'
print ''
print ' -en converts hex to base58'
print ' -de converts base58 to hex'
print
print ' -pub public_key_to_bc_address'
print ' -adr bc_address_to_hash_160'
print
print ' -sec sec_to_bc_key'
print ' -prv bc_key_to_sec'
print
To answer your specific question, based on above code you could use this command:
hashlib.sha256('0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'.decode('hex_codec')).digest().encode('hex_codec').upper()

Python 3: ValueError: invalid literal for int() with base 10: '0001.0110010110010102e+22'

I'm a beginner, so sorry if this is obvious.
I'm at a loss here. I've been trying to make an encryption/decryption program, but I keep getting this error. I'm aware that there are other questions on this issue, but I still can't resolve it.
Encryptor:
import binascii
def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
return bits.zfill(8 * ((len(bits) + 7) // 8))
def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
n = int(bits, 2)
return int2bytes(n).decode(encoding, errors)
def int2bytes(i):
hex_string = '%x' % i
n = len(hex_string)
return binascii.unhexlify(hex_string.zfill(n + (n & 1)))
#ENCRYPTION ALGORITHM
algorithm = 61913299
#ASCII ----> NUMBERS
raw = input("Enter text to encrypt:")
binary = text_to_bits(raw)
binary = int(binary)
algorithm = int(algorithm)
encrypted = binary * algorithm
encrypted = str(encrypted)
print(encrypted)
print("Done")
Decryptor:
import sys
import time
def to_bin(string):
res = ''
for char in string:
tmp = bin(ord(char))[2:]
tmp = '%08d' %int(tmp)
res += tmp
return res
def to_str(string):
res = ''
for idx in range(len(string)/8):
tmp = chr(int(string[idx*8:(idx+1)*8], 2))
res += tmp
return res
incorrectpasswords = 0
password=("password")
originpassword = password
x = 1
algorithm = 61913299
while x==1:
passwordattempt =input("Enter Password:")
if passwordattempt == password:
print("Correct")
x = 2
if passwordattempt!= password:
print("Incorrect")
incorrectpasswords = incorrectpasswords + 1
if incorrectpasswords > 2:
if x == 1:
print("Too many wrong attempts, please try again in one minute.")
time.sleep(60)
encrypted = input("Enter numbers to unencrypt:")
encrypted = int(encrypted)
one = encrypted / algorithm
size = sys.getsizeof(one)
one = str(one).zfill(size + 1)
one = int(one)
unencrypted = to_str(one)
x = unencrypted
For the conversion between binary and text, and text and binary, I used some code I found online.
I believe your code is not working because:
one = encrypted / algorithm
generates a float
to turn your string back into a number you should apply
eval(one)
or
float(one)
instead of
int(one)
(You can also turn it into an int after applying float or eval)
alternatively you might be able to get it by using integer division // as opposed to / , which will make one the type int by flooring the decimal result of the divison, but I'm not sure if that is the behavior you are looking for
Example in python 3 shell:
>>> import sys
>>> one = 15/25
>>> size = sys.getsizeof(one)
>>> one = str(one).zfill(size+1)
>>> one
'00000000000000000000000.6'
>>> type(one)
<class 'str'>
>>> one = eval(one)
>>> one
0.6
>>> type(one)
<class 'float'>

Complex Python object to JSON Conversion

I need to convert a complex python object to JSON, by complex I mean an object that contains int variables, string variables, and 2 lists of custom objects.
My Python object's constructor is:
def __init__(self, skills="",vid=""):
self.Skills = list([])
for skillID in skills.split("-"):
if not skillID == "":
tmpSkill = Skill()
tmpSkillObj = DBCommands.getSkill(skillID)
tmpSkill.ID = tmpSkillObj[0][0] #tmpSkillObj[0][0]
tmpSkill.Name = tmpSkillObj[0][1]
tmpSkill.isMain = True
tmpSkill.CurrentlyTesting = False
tmpSkill.isSub = False
tmpSkill.Level = 0
tmpSkill.Tested = False
tmpSkill.Score = 0
tmpSkill.Confidence = 0
tmpSkill.BestScore = 0
tmpSkill.ParentID = 0
self.Skills.append(tmpSkill)
self.AskedQuestions.append(tmpSkill)
self.Skills = list(self.Skills)
if not skills == "":
self.Skills[0].CurrentlyTesting = True #Start testing the first skill
if not vid == "":
self.VacancyID = int(vid)
self.PlayerID = 0
self.Score = float(0)
self.AskedQuestions = list([])
self.MaxLevel = 0
self.AssessmentIsFinished = False
I need a mechanism to encode the object and decode it.
Encode:
import base64
import pickle
token = base64.b64encode(pickle.dumps(token,-1))
Decode:
import pickle
import base64
Obj = pickle.loads(base64.b64decode(token))

Converting .raw file into Hex

I have a .raw image file, and I'd like to use python3 to read all the data from the file and print a hex dump of this image.
If possible, i'd like it to run in the terminal window.
This is the code I have found and adapted so far:
import sys
src = sys.argv[1]
def hexdump( src, length=16, sep='.' ):
result = [];
# Python3 support
try:
xrange(0,1);
except NameError:
xrange = range;
for i in xrange(0, len(src), length):
subSrc = src[i:i+length];
hexa = '';
isMiddle = False;
for h in xrange(0,len(subSrc)):
if h == length/2:
hexa += ' ';
h = subSrc[h];
if not isinstance(h, int):
h = ord(h);
h = hex(h).replace('0x','');
if len(h) == 1:
h = '0'+h;
hexa += h+' ';
hexa = hexa.strip(' ');
text = '';
for c in subSrc:
if not isinstance(c, int):
c = ord(c);
if 0x20 <= c < 0x7F:
text += chr(c);
else:
text += sep;
result.append(('%08X: %-'+str(length*(2+1)+1)+'s |%s|') % (i, hexa, text));
return '\n'.join(result);
if __name__ == "__main__":
print(hexdump(src, length=16, sep='.'))
I've been using the command in the terminal:
python3 nameoffile.py nameofrawfile.raw
and it just gives me the hex values of the name of the raw file. I'd like it to read the raw file then give be all the data from it in hex.
Thanks.
EDIT: I'd like to use python as once the file is represented in hex values, I'd like to do further processing on it using python.
One-liner:
$ python -c \
"import codecs; print(codecs.encode(open('file.raw', 'rb').read(), 'hex').decode())"
The problem is you pass the name of the file to hexdump() which treats it like data. The following corrects that and applies other relatively minor fixes to your code (and seems to work in my limited testing):
try:
xrange
except NameError: # Python3
xrange = range
def hexdump(filename, length=16, sep='.'):
result = []
with open(filename, 'rb') as file:
src = file.read() # Read whole file into memory
for i in xrange(0, len(src), length):
subSrc = src[i:i+length]
hexa = ''
isMiddle = False;
for h in xrange(0,len(subSrc)):
if h == length/2:
hexa += ' '
h = subSrc[h]
if not isinstance(h, int):
h = ord(h)
h = hex(h).replace('0x','')
if len(h) == 1:
h = '0'+h;
hexa += h+' '
hexa = hexa.strip(' ')
text = ''
for c in subSrc:
if not isinstance(c, int):
c = ord(c)
if 0x20 <= c < 0x7F:
text += chr(c)
else:
text += sep;
result.append(('%08X: %-'+str(length*(2+1)+1)+'s |%s|') %
(i, hexa, text))
return '\n'.join(result)
if __name__ == "__main__":
import sys
filename = sys.argv[1]
print(hexdump(filename, length=16, sep='.'))

Categories

Resources