TypeError: Strings must be encoded before hashing (Python)

avatar
Borislav Hadzhiev

Last updated: Apr 8, 2024
3 min

banner

# TypeError: Strings must be encoded before hashing (Python)

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').

typeerror strings must be encoded before hashing

Here is an example of how the error occurs.

main.py
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).

shell
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.

# Pass a bytes object to the hashing algorithm

To solve the error, pass a bytes object to the method instead, e.g. my_str.encode('utf-8').

main.py
import hashlib my_str = 'bobbyhadz.com' # ✅ Encode str to bytes my_hash = hashlib.sha256(my_str.encode('utf-8')).hexdigest() # 👇️ c5fd426de8044e3ab34fd5005c0da08383a15fd018aeb76f903fb59c6de537de print(my_hash)

pass bytes object to hashing algorithm

The str.encode() method returns an encoded version of the string as a bytes object. The default encoding is utf-8.

# Prefix the string with b'' to encode it to a bytes object

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.

main.py
import hashlib my_hash = hashlib.sha256(b'bobbyhadz.com').hexdigest() # 👇️ c5fd426de8044e3ab34fd5005c0da08383a15fd018aeb76f903fb59c6de537de print(my_hash)

prefix string with b to encode it to bytes

Prefixing the string with 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.

main.py
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.

# Using the digest() and hexdigest() methods

You 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.

main.py
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())

using digest and hexdigest methods

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.

main.py
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.

main.py
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.

# Checking what type of object a variable stores

If you aren't sure what type of object a variable stores, use the built-in type() class.

main.py
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

checking the type of the object

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.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.