Hello everyone,
Michael here, and in today’s lesson, we’ll explore Python encryption, SHA style.
What is SHA encryption? SHA stands for Secure Hash Algorithm, and it is what’s known as a cryptographic hash function. The SHA algorithms were developed by the US National Security Agency (NSA) and published by the National Institute of Standards and Technology*. SHA is also not a symmetric-key or an asymmetric-key algorithm, as the main purpose of SHA is data security and integrity, not encrypting/decrypting communications.
Now, let’s dive into some SHA coding!
- *The National Institute of Standards and Technology is an agency under the US Department of Commerce.
Types of SHA hashing functions
There are five different types of SHA hashing functions. Let’s explore each of them:
SHA-256-This hashing function will produce a 256-bit hashSHA-384-This hashing function will produce a 384-bit (or 48-byte) hashSHA-224-This hashing function will produce a 224-bit (or 28-byte) hashSHA-512-This hashing function will produce a 512-bit (or 64-byte) hash; because of the long hash output, this is seen as one of the more secure hashing algorithmsSHA-1-This was the first SHA hashing function developed by the NSA and produced a 160-bit (or 20-byte) hash; however, this algorithm was found to have many security weaknesses and was thus phased out after 2010
Encrypting text, SHA style
Now that we know about the five different types of hashing functions, let’s see how they work on a text string in Python!
First, let’s import any necessary modules!
import hashlib
The hashlib module will be the only one we’ll need for this post. No need to pip install it since it comes built-in as long as your Python version is 2.5 or higher (and Python 2 has long since been sunset).
Next, let’s set the text we’ll use along with the SHA-256 hash of the text:
text = 'Michaels Programming Bytes: Byte sized programming classes for all coding learners'
SHA256 = hashlib.sha256(text.encode())
print(SHA256.hexdigest())
9854a9d55046c36afafbe47cbaa21ab85c8137d81955c3e344d76156a636a66b
As you see here, we used the name and tagline of this blog for our SHA demonstration. For our SHA encryption, keep these two methods in mind-.encode() and .hexdigest()-as we will use them throughout our demonstrations of the SHA hashing functions.
The .encode() method encodes the text string into a hexadecimal hash while the .hexdigest() method will display the hexadecimal hash.
- Also, if you want to learn more about or need a refresher on hexadecimal numbering systems, check out this post from February 2019-https://michaelsprogrammingbytes.com/java-lesson-5-java-numbering-systems/ (yes I know it’s a Java lesson but it still explains the basics of hexadecimal numbering).
As you can see here, we have generated a SHA-256 hash from our text with just two lines of code!
Now, if your curious what the decimal number of this hash equals, let’s check it out for fun:
68901140284153216712479841246928981776103555384517524587226404491787878442603
It’s a large, 77-digit number that’s roughly 68 quattuorvigintillion (this is a number followed by 75 zeroes). Quite a big number to come out of that hash!
Next, let’s try the SHA-384 encryption method:
SHA384 = hashlib.sha384(text.encode())
print(SHA384.hexdigest())
2777dfcb92166aa95f0796e3ed4edc12d7da9db3226c8831b40aca5576e8aafa106bb26b3eafe07fc9124238e5e7a6be
This time, we appear to have gotten a larger hash than we did from the SHA-256 function. What could be the decimal number of this hash?
6074720975275609937364706669124284930019665411073401970740713484318034757229843193804707918050212936621238163842750
Now, this number is even larger-it’s approximately 6 septentrigintillion (this is a number followed by 114 zeroes). I honestly never even seen such massive numbers, but as a numbers guy, massive numbers are fun to learn about!
Next, let’s try the SHA-224 method:
SHA224 = hashlib.sha224(text.encode())
print(SHA224.hexdigest())
8ed6b6c67f8f543d41472f2b0da146516cc6e28a20637d4fc3018518
Since SHA-224 uses less bits/bytes than the SHA-384 and SHA-256 functions, it makes sense that the generated hash would be shorter than the hashes generated from those functions.
I imagine that the decimal number would be shorter too:
15042673619469762912744046603652644639808686980332500102671983805720
Not surprisingly, the decimal number from this hash is also shorter, but still fairly massive-it’s approximately 15 unvigintillion (a number followed by 66 zeroes).
Next, let’s try the SHA-512 method:
SHA512 = hashlib.sha512(text.encode())
print(SHA512.hexdigest())
8d42047543b1bea09199838101c6ba0b5fb5d2631c1bb9b772333f2faa51b7cd0c53946e79758475929244d33e02b8e8cd994d79c63747ffdeeec3d6e9a66719
Since SHA-512 generates the largest hashes of all the SHA hashing functions, it’s not surprising that the generated hash is so large.
With a hash so large, I can only imagine what the decimal number would look like:
7398275510411850389223316484636795314726283670587045768118856918282820596862752633935810532260756989519458279298581715671072351034597240609479775136147225
The number above is approximately 7 quinquagintillion, which sounds like a word Dr. Seuss would make up, but it’s a number followed by 153 zeroes.
Last but not least, let’s try the retired, and original, SHA hashing function on our text-SHA-1:
SHA1 = hashlib.sha1(text.encode())
print(SHA1.hexdigest())
5ed4ecb61ff2323823781c514cbe2181e034a186
Since the hashes generated from the SHA-1 function use the least bytes (20) from the five functions we explored, the generated hash would also be the shortest of the five hashes we’ve generated.
With that said, it won’t be surprising that the decimal number of this hash is also fairly short:
541393510912863704690262334257797793251671187846
Even though this number is shorter than the other four numbers we got from the other four hashes, it’s still fairly massive-541 quattuordecillion (a number followed by 45 zeroes).
All in all, we got to see the power of SHA hashing functions through some simple text encryption. The massive decimal numbers we got from each of the generated hashes put the power of the SHA algorithm into perspective (plus, I had fun exploring massive numbers).
An interesting application of SHA hashing algorithms
Before we go, I wanted to explain an interesting application of the SHA hashing algorithm-Bitcoin mining. Yes, Bitcoin mining utilizes the SHA-256 algorithm during the mining process-this is because SHA-256 is both computationally efficient and offers a good deal of security throughout the process. Granted, SHA-512 could also offer a great deal of security, but the hashes also take up a lot of memory.
So, how would one mine Bitcoin? Check out this illustration below for an explanation:

For a very simplistic explanation of Bitcoin mining, a miner would need to utilize a very powerful computer (with processing power much greater than even your standard gaming laptop) to continually generate SHA-256 hashes until the correct hash is found. Once that happens, the miner is entitled to some Bitcoin as a reward. How much Bitcoin they get is determined by Bitcoin’s value at a given time-for instance, the reward as of August 2024 is 3.125 Bitcoin (or 3 1/8 Bitcoin).
Here’s the GitHub link to the script from this post (SHA is the script name)-https://github.com/mfletcher2021/blogcode/blob/main/SHA.py.
Thanks for reading!
Michael