SHA-256 / MD5 Hash Generator
What is a Cryptographic Hash?
A cryptographic hash function takes an input of any size and produces a fixed-length string of characters — the digest — that looks random but is deterministic: the same input always produces the same output. Change a single bit and the digest changes completely, a property called the avalanche effect. Unlike Base64 encoding, hashing is a one-way operation. There is no key, no secret, and no way to reverse the process to recover the original input.
Hashes serve two purposes: integrity verification (confirming a file or message has not been altered) and commitment (proving you knew a value without revealing it). Passwords are stored as hashes so that a database leak does not expose the original credentials; downloads are published alongside checksums so you can verify the file arrived intact.
SHA-256 vs MD5 — Which Should You Use?
MD5 was designed in 1991 and produces a 128-bit (32-character hex) digest. It is fast and compact, but it is cryptographically broken — researchers demonstrated practical collision attacks in 2004, and in 2012 the Flame malware exploited an MD5 collision in Windows Update certificates. MD5 should never be used for security. It is still acceptable as a non-cryptographic checksum where collision resistance does not matter: verifying a download, deduplicating files, or building a cache key.
SHA-256 is part of the SHA-2 family, published by NIST in 2001. It produces a 256-bit (64-character hex) digest. No practical collision or preimage attacks exist. It is the default choice for anything security-related: certificate signatures (TLS certificates use SHA-256), blockchain proof of work (Bitcoin), git commit identifiers (since Git 2.29), content-addressable storage, and HMAC-based authentication such as the signatures in JWTs signed with HS256.
Hash Algorithm Comparison
| Algorithm | Digest size | Hex chars | Status | Use case |
|---|---|---|---|---|
| MD5 | 128 bits | 32 | Broken — collisions practical | Non-security checksums only |
| SHA-1 | 160 bits | 40 | Deprecated — collision demonstrated (SHAttered, 2017) | Legacy systems, git (transitioning away) |
| SHA-256 | 256 bits | 64 | Secure | General purpose, TLS, blockchain, HMAC |
| SHA-384 | 384 bits | 96 | Secure | TLS cipher suites requiring >256-bit security |
| SHA-512 | 512 bits | 128 | Secure | Larger margin, slightly faster on 64-bit CPUs |
When to Use Each Algorithm
- Password storage: None of these directly. Use bcrypt, scrypt, or Argon2 — purpose-built password hashing functions that are deliberately slow to resist brute-force attacks. SHA-256 is too fast: a GPU can compute billions of SHA-256 hashes per second.
- File integrity: SHA-256 is the standard. Linux package managers, Docker image digests, and Subresource Integrity (SRI) tags all use it.
- API request signing: HMAC-SHA256 — the mechanism behind AWS Signature V4, Stripe webhooks, and GitHub webhook verification.
- Quick deduplication: MD5 is fine when you only need to detect accidental duplicates, not adversarial ones. It is faster and the 32-character digest is more compact.
- Git: SHA-1 historically, migrating to SHA-256. The SHAttered collision does not threaten git in practice because crafting a collision that produces a valid git object is far harder than the bare hash collision.
How Hashing Works, Step by Step
Every hash function follows the same pattern. The input is padded to a multiple of the block size (512 bits for SHA-256, 512 bits for MD5). Padding always includes a 1 bit, then zeros, then the original message length. The padded message is split into blocks, and each block is processed through a compression function that mixes it with the running state. The final state is the digest.
The compression function is where the algorithms diverge. MD5 uses four rounds of 16 operations each, with bitwise functions and precomputed sine-table constants. SHA-256 uses 64 rounds with a more complex mixing schedule and different constants derived from the first 64 primes. The additional rounds and wider state are what give SHA-256 its collision resistance.
How to Hash in Every Language
JavaScript / Node.js
// Browser (SHA-256)
const data = new TextEncoder().encode("hello");
const hash = await crypto.subtle.digest("SHA-256", data);
const hex = [...new Uint8Array(hash)]
.map(b => b.toString(16).padStart(2, "0")).join("");
// Node.js
const { createHash } = require("crypto");
const hex = createHash("sha256").update("hello").digest("hex");
Python
import hashlib
hashlib.sha256(b"hello").hexdigest()
hashlib.md5(b"hello").hexdigest()
Java
import java.security.MessageDigest;
byte[] hash = MessageDigest.getInstance("SHA-256")
.digest("hello".getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte b : hash) sb.append(String.format("%02x", b));
Bash / Command Line
# SHA-256
echo -n "hello" | sha256sum
# MD5
echo -n "hello" | md5sum
# File hash
sha256sum myfile.tar.gz
Go
import (
"crypto/sha256"
"fmt"
)
h := sha256.Sum256([]byte("hello"))
fmt.Printf("%x\n", h)
Verifying File Integrity with Checksums
When a project publishes a download alongside a .sha256 file, the workflow is straightforward. Download the file, hash it locally, and compare the digests. If they match, the file arrived intact. If they differ, the download was corrupted or tampered with.
# Download and verify
curl -O https://example.com/release.tar.gz
curl -O https://example.com/release.tar.gz.sha256
sha256sum -c release.tar.gz.sha256
This tool performs the same operation in your browser — drop the file onto the drop zone, select SHA-256, and compare the output to the published digest. Nothing is uploaded, so verifying a confidential binary does not leak it.
Common Hashing Mistakes
- Using MD5 or SHA-256 directly for passwords. Both are designed to be fast. An attacker with a GPU can try billions of candidates per second. Password hashing requires a function that is deliberately slow and memory-hard — bcrypt, scrypt, or Argon2id.
- Comparing hashes in a timing-sensitive way. A simple string comparison (
===) leaks information about which character first differed. In security contexts, use a constant-time comparison function. - Hashing without encoding to bytes first. The same string can produce different byte sequences in different encodings. Always encode to UTF-8 before hashing, just as with Base64 encoding. Two systems that disagree on encoding will produce different hashes from the same text.
- Forgetting the
-nflag with echo.echo "hello"appends a newline;echo -n "hello"does not. The newline is an extra byte, so the hash is different. This is the most common reason a command-line hash does not match a programmatic one. - Confusing encoding with hashing. Base64 and hex are encodings — they are reversible. SHA-256 is a hash — it is not. Encoding a password in Base64 does not protect it; hashing it (with a proper password function) does.
Hash Lengths at a Glance
The digest is always the same length regardless of input size. An empty string and a gigabyte file produce the same number of hex characters.
| Algorithm | Hex output | Example (hash of "hello") |
|---|---|---|
| MD5 | 32 chars | 5d41402abc4b2a76b9719d911017c592 |
| SHA-1 | 40 chars | aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d |
| SHA-256 | 64 chars | 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 |
| SHA-384 | 96 chars | 59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f |
| SHA-512 | 128 chars | 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 |
Subresource Integrity (SRI)
When you load a script from a CDN, the CDN could theoretically serve malicious code. Subresource Integrity lets browsers verify a fetched resource against a hash you commit to in your HTML:
<script src="https://cdn.example.com/lib.js"
integrity="sha384-oqVuAfXRKap7fdg..."
crossorigin="anonymous"></script>
The browser hashes the downloaded file and refuses to execute it if the digest does not match. SRI uses SHA-256, SHA-384, or SHA-512 — never MD5 or SHA-1. The hash is Base64-encoded (not hex), so if you need to convert between formats, our Base64 encoder handles that.
Hashing in Cron Jobs and Automation
Scheduled scripts that fetch remote data often need to detect whether anything changed since the last run. Hashing the fetched content and comparing it to the stored hash from the previous run is cheaper and more reliable than tracking modification timestamps, which many APIs do not provide. If you are writing those schedules, our cron expression generator shows the next run times so you can verify the interval before deployment.
Frequently Asked Questions
echo without -n does). Case differences in the hex output (uppercase vs lowercase) do not mean the hashes differ — the underlying bytes are the same.