Skip to Content
Course content

69: Digest for Hashing (MD5, SHA)

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're running a massive warehouse. You have thousands of crates of different sizes and weights. Instead of lugging a 500lb crate across the room every time you need to verify its contents, you use a specialized "compression stamp." This stamp takes all the details of the crate—the weight, the dimensions, the items inside—and crushes that information down into a single, unique 10-digit serial number.

Here is the catch: the stamp is a one-way street. You can turn a crate into a serial number, but you can't look at the serial number and magically recreate the crate. However, if you have two crates and they both produce the exact same serial number, you can be almost certain they contain the exact same items. If you change even one tiny screw inside the crate, the serial number changes completely.

In Ruby, that "compression stamp" is what we call a Digest. The "crate" is your data (like a string or a file), and the "serial number" is the hash.

Getting the Digest Library on Board

Ruby doesn't load hashing tools by default because you don't need them for every single script. You'll need to pull in the digest library. It's part of the standard library, so you don't need to install a gem, just require it.

require 'digest'

# Let's hash a simple string
input = "The quick brown fox jumps over the lazy dog"
hash = Digest::SHA256.hexdigest(input)

puts hash
# Output: ef797c8118f0272 FCC... (a long string of hex characters)

Picking Your Algorithm: MD5 vs. SHA

When you look at the Digest module, you'll see a few different options. I want to be very clear here: not all hashes are created equal. Depending on what you're doing, choosing the wrong one can be a security disaster.

  • MD5: This is the old guard. It's fast, but it's "broken" from a security standpoint. People have found ways to create "collisions" (two different inputs that produce the same hash). I only use MD5 today if I'm checking if a file was downloaded correctly (a checksum), never for passwords.
  • SHA-1: A step up from MD5, but also largely considered insecure for high-stakes cryptography these days.
  • SHA-256 (and SHA-512): This is where you should spend most of your time. It's significantly more secure and is the industry standard for things like blockchain and secure file verification.
# MD5 is quick and dirty
puts Digest::MD5.hexdigest("my_secret_password") 

# SHA256 is the professional choice
puts Digest::SHA256.hexdigest("my_secret_password")

The Avalanche Effect

One of the coolest things about hashing is what we call the "avalanche effect." In a good hashing algorithm, if you change one single character in your input, the entire output changes unpredictably. It doesn't just change one letter of the hash; it transforms the whole thing.

Try running this in your head: if "Password123" gives you a specific hash, you might think "Password124" would look almost identical. It doesn't. It looks like a completely different universe of characters. This is why hashing is so effective for verifying data integrity; you can't "guess" your way toward the original input by looking at the output.

Handling Large Files Without Crashing

If you try to read a 2GB ISO file into a string and then hash it, you're going to run out of RAM and your program will crash. I've seen this happen to plenty of juniors. Instead of loading the whole file at once, you can "feed" the digest object in chunks.

sha256 = Digest::SHA256.new
File.open('huge_installer.exe', 'rb') do |file|
  while chunk = file.read(4096) # Read 4KB at a time
    sha256.update(chunk)
  end
end

puts sha256.hexdigest

By using .new and .update, we keep the memory footprint tiny regardless of how big the file is. We're essentially feeding the "blender" one handful of ingredients at a time until everything is processed.




📋 Practical Task

Build a Configuration File Integrity Monitor

Your goal is to create a script that can detect if a critical configuration file has been tampered with.

Requirements:

  1. Create a text file named config.txt with some dummy settings (e.g., timeout=30\nport=8080).
  2. Write a Ruby script that:
    • Generates a SHA-256 hash of the current config.txt and saves that hash into a second file called checksum.txt.
    • Includes a "verify" method that reads the current config.txt, hashes it, and compares it against the value stored in checksum.txt.
    • Prints "Integrity Verified" if they match, and "WARNING: File Tampered!" if they don't.

Test your logic: Run your verification, then manually open config.txt, change one single character (like changing port=8080 to port=8081), and run your verification again to see the alarm trigger.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.