I want to convert a hash256 object to a 32-byte integer first, and then pack it into a bytearray.
>>> import hashlib
>>> hashobj = hashlib.sha256('something')
>>> val_hex = hashobj.hexdigest()
>>> print val_hex
3fc9b689459d738f8c88a3a48aa9e33542016b7a4052e001aaa536fca74813cb
>>> print len(val_hex)
64
The hex string is 64-byte instead of 32-byte, which is not what I want.
>>> val = hashobj.digest()
>>> print val
?ɶ?E?s????????5Bkz@R???6??H?
>>> print len(val)
32
This is a 32-byte string and I want to convert it to a 32-byte integer.
It gave me an error message when I try:
>>> val_int = int(val, 10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '?\xc9\xb6\x89E\x9ds\x8f\x8c\x88\xa3\xa4\x8a\xa9\xe35B\x01kz@R\xe0\x01\xaa\xa56\xfc\xa7H\x13\xcb'
What should I do to get my int_val?
And how can I use struct to pack it (32-byte) to a bytearray? I found the longest format in python struct document is 'Q' which is only 8-byte.
Thank you very much.
The Python hashlib module is an interface for hashing messages easily. This contains numerous methods which will handle hashing any raw message in an encrypted format. The core purpose of this module is to use a hash function on a string, and encrypt it so that it is very difficult to decrypt it.
To convert bytes to int in Python, use the int. from_bytes() method. A byte value can be interchanged to an int value using the int. from_bytes() function.
hexdigest () Like digest() except the digest is returned as a string object of double length, containing only hexadecimal digits. This may be used to exchange the value safely in email or other non-binary environments.
The simplest way in Python 2 to get the integer value of the SHA-256 digest is via the hexdigest. Alternatively, you can loop over the bytearray constructed from the binary digest. Both methods are illustrated below.
import hashlib
hashobj = hashlib.sha256('something')
val_hex = hashobj.hexdigest()
print val_hex
# Build bytearray from binary digest
val_bytes = bytearray(hashobj.digest())
print ''.join(['%02x' % byte for byte in val_bytes])
# Get integer value of digest from the hexdigest
val_int = int(val_hex, 16)
print '%064x' % val_int
# Get integer value of digest from the bytearray
n = 0
for byte in val_bytes:
n = n<<8 | byte
print '%064x' % n
output
3fc9b689459d738f8c88a3a48aa9e33542016b7a4052e001aaa536fca74813cb
3fc9b689459d738f8c88a3a48aa9e33542016b7a4052e001aaa536fca74813cb
3fc9b689459d738f8c88a3a48aa9e33542016b7a4052e001aaa536fca74813cb
3fc9b689459d738f8c88a3a48aa9e33542016b7a4052e001aaa536fca74813cb
In Python 3, we can't pass a plain text string to the hashlib
hash function, we must pass a bytes
string or a bytearray
, eg
b'something'
or
'something'.encode('utf-8')
or
bytearray('something', 'utf-8')
We can simplify the second version to
'something'.encode()
since UTF-8 is the default encoding for str.encode
(and bytes.decode()
).
To perform the conversion to int
, any of the above techniques can be used, but we also have an additional option: the int.from_bytes
method. To get the correct integer we need to tell it to interpret the bytes as a big-endian number:
import hashlib
hashobj = hashlib.sha256(b'something')
val = int.from_bytes(hashobj.digest(), 'big')
print('%064x' % val)
output
3fc9b689459d738f8c88a3a48aa9e33542016b7a4052e001aaa536fca74813cb
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With