Last updated: Apr 8, 2024
Reading time·3 min
The Python "TypeError: Strings must be encoded before hashing" occurs when we pass a string to a hashing algorithm.
To solve the error, use the encode()
method to encode the string to a bytes
object, e.g. my_str.encode('utf-8')
.
Here is an example of how the error occurs.
import hashlib my_str = 'bobbyhadz.com' # ⛔️ TypeError: Strings must be encoded before hashing my_hash = hashlib.sha256(my_str).hexdigest()
Your error message might also be the following (depending on your version of Python).
TypeError: Unicode-objects must be encoded before hashing
We used sha256()
to create a SHA-256 hash object and passed a string to it,
which caused the error.
To solve the error, pass a bytes
object to the method instead, e.g.
my_str.encode('utf-8')
.
import hashlib my_str = 'bobbyhadz.com' # ✅ Encode str to bytes my_hash = hashlib.sha256(my_str.encode('utf-8')).hexdigest() # 👇️ c5fd426de8044e3ab34fd5005c0da08383a15fd018aeb76f903fb59c6de537de print(my_hash)
The str.encode() method returns an
encoded version of the string as a bytes object. The default encoding is
utf-8
.
If you have a string literal, and not a string stored in a variable, you can
prefix the string with b
to encode it to a bytes object.
import hashlib my_hash = hashlib.sha256(b'bobbyhadz.com').hexdigest() # 👇️ c5fd426de8044e3ab34fd5005c0da08383a15fd018aeb76f903fb59c6de537de print(my_hash)
b
achieves the same result as calling the encode()
method on it, but can only be used if you have a string literal, and not a string stored in a variable.Notice that we don't have to use the str.encode()
method when we have a
bytes
object.
import hashlib # ✅ with a String my_str = 'bobbyhadz.com' my_hash = hashlib.sha256(my_str.encode('utf-8')).hexdigest() # 👇️ c5fd426de8044e3ab34fd5005c0da08383a15fd018aeb76f903fb59c6de537de print(my_hash) # ---------------------------------------------- # ✅ with a Bytes object my_bytes = b'bobbyhadz.com' my_hash = hashlib.sha256(my_bytes).hexdigest() # 👇️ c5fd426de8044e3ab34fd5005c0da08383a15fd018aeb76f903fb59c6de537de print(my_hash)
The first example uses a string, so we had to call the str.encode()
method to
convert the string to bytes in the call to the sha256()
method.
The second example uses a bytes object (the b''
prefix), so it can directly
get passed to the sha256()
method.
digest()
and hexdigest()
methodsYou can get the digest of the concatenation of the data fed to the hash object
by using the digest()
or hexdigest()
methods.
Here is an example that uses the digest()
method instead.
import hashlib str_1 = 'first' str_2 = 'second' m = hashlib.sha256() m.update(str_1.encode('utf-8')) m.update(str_2.encode('utf-8')) # 👇️ b'\xda\x83\xf6>\x1aG0\x03q,\x18\xf5\xaf\xc5\xa7\x90D"\x19C\xd1\x08<|Zz\xc7#m\x85\xe8\xd2' print(m.digest()) # 👇️ da83f63e1a473003712c18f5afc5a79044221943d1083c7c5a7ac7236d85e8d2 print(m.hexdigest())
We used the str.encode()
method to convert the strings to bytes objects before
passing them to the
hash.update()
method.
The hash.update()
method updates the hash object with the supplied bytes-like
object.
We could have also prefixed the string literals with b
to convert them to
bytes.
import hashlib # ✅ declare bytes objects bytes_1 = b'first' bytes_2 = b'second' m = hashlib.sha256() m.update(bytes_1) m.update(bytes_2) # 👇️ b'\xda\x83\xf6>\x1aG0\x03q,\x18\xf5\xaf\xc5\xa7\x90D"\x19C\xd1\x08<|Zz\xc7#m\x85\xe8\xd2' print(m.digest()) # 👇️ da83f63e1a473003712c18f5afc5a79044221943d1083c7c5a7ac7236d85e8d2 print(m.hexdigest())
The code sample declares bytes objects directly, so we can pass them to the
hash.update()
method without using encode.
The hash.hexdigest() method is an alternative to using hash.digest().
Here is a more condensed version of the previous code sample.
import hashlib my_bytes = b'first second' my_str = hashlib.sha256(my_bytes).hexdigest() # 👇️ 92088ec140fc553e4b1ede202edccb65a807bbf8a38d765a3ad38013c0f13688 print(my_str)
The hash.digest
method returns the digest of the data passed to the update()
method. The method returns a bytes object which may contain bytes in the whole
range from 0
to 255
.
The hash.hexdigest
method is like digest
but the digest is returned as a
string object of double length and contains only hexadecimal digits.
The method is often used when you need to safely send the value over the network, e.g. via email.
If you aren't sure what type of object a variable stores, use the built-in
type()
class.
my_bytes = 'hello'.encode('utf-8') print(type(my_bytes)) # 👉️ <class 'bytes'> print(isinstance(my_bytes, bytes)) # 👉️ True my_str = 'hello' print(type(my_str)) # 👉️ <class 'str'> print(isinstance(my_str, str)) # 👉️ True
The type class returns the type of an object.
The isinstance() function
returns True
if the passed-in object is an instance or a subclass of the
passed-in class.