DevToolsForYou
Auth & Security

How to Generate Cryptographic Hashes

A practical guide to hashing — understand what hash functions do, the difference between MD5, SHA-1, SHA-256, and SHA-512, and how to generate hashes in JavaScript, Python, and the terminal.

3 min readUpdated Apr 11, 2026

What is a hash function?

A cryptographic hash function takes input data of any size and produces a fixed-length output called a digest or hash. The same input always produces the same output, but even a single character change produces a completely different hash. Crucially, it is computationally infeasible to reverse the process — you cannot recover the input from the hash. This makes hashes useful for verifying data integrity, storing passwords (with proper salting), and signing data.

MD5 vs SHA-1 vs SHA-256 vs SHA-512

Different algorithms produce different digest lengths and have different security properties. MD5 and SHA-1 are broken for security purposes — collision attacks are practical. Use SHA-256 or SHA-512 for any security-sensitive application.

text
Algorithm  Output length  Status      Common uses
─────────  ─────────────  ──────────  ─────────────────────────────
MD5        128 bits (32 hex)  Broken    File checksums, non-security deduplication
SHA-1      160 bits (40 hex)  Broken    Legacy systems, git object IDs
SHA-256    256 bits (64 hex)  Secure    TLS certificates, JWT signing, file integrity
SHA-512    512 bits (128 hex) Secure    Higher-security applications

Generating hashes in JavaScript

The Web Crypto API (available in all modern browsers and Node.js 15+) provides SubtleCrypto.digest() for SHA-family hashes. For Node.js, the built-in crypto module is simpler to use.

javascript
// Browser / Node.js 15+ — Web Crypto API
async function sha256(message) {
  const msgBuffer = new TextEncoder().encode(message);
  const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
}

const hash = await sha256("hello world");
console.log(hash);
// "b94d27b9934d3e08a52e52d7da7dabfac484efe04294e576..."

// Node.js — crypto module (simpler)
import { createHash } from "crypto";
createHash("sha256").update("hello world").digest("hex");
// same result

Generating hashes in Python

Python's built-in hashlib module supports MD5, SHA-1, SHA-256, SHA-512, and more. Always encode the string to bytes before hashing.

python
import hashlib

message = "hello world"

# SHA-256
sha256 = hashlib.sha256(message.encode()).hexdigest()
print(sha256)
# "b94d27b9934d3e08a52e52d7da7dabfac484efe04294e576..."

# MD5
md5 = hashlib.md5(message.encode()).hexdigest()
print(md5)  # "5eb63bbbe01eeed093cb22bb8f5acdc3"

# Hash a file
import hashlib
with open("file.zip", "rb") as f:
    file_hash = hashlib.sha256(f.read()).hexdigest()
print(file_hash)

Generating hashes from the command line

macOS and Linux ship with shasum and md5sum (or md5 on macOS). These are useful for verifying downloaded file checksums.

bash
# SHA-256 of a string
echo -n "hello world" | shasum -a 256
# b94d27b9934d3... -

# SHA-256 of a file
shasum -a 256 file.zip

# MD5
md5 file.zip          # macOS
md5sum file.zip       # Linux

# SHA-512
echo -n "hello" | shasum -a 512

Hashing passwords — use bcrypt, not SHA-256

SHA-256 is fast, which makes it bad for password hashing — an attacker can try billions of guesses per second. Password hashing requires a slow, salted algorithm designed to resist brute force: bcrypt, Argon2, or PBKDF2. Never store plain SHA-256 of passwords in a database.

javascript
// Node.js — bcrypt
import bcrypt from "bcrypt";

// Hash a password (cost factor 12 = ~250ms on modern hardware)
const hash = await bcrypt.hash("user_password", 12);

// Verify
const match = await bcrypt.compare("user_password", hash); // true

// Python — bcrypt
import bcrypt
hashed = bcrypt.hashpw(b"user_password", bcrypt.gensalt(rounds=12))
bcrypt.checkpw(b"user_password", hashed)  # True
Frequently asked questions

Can two different inputs produce the same hash?

Theoretically yes — this is called a collision. For MD5 and SHA-1, practical collision attacks exist. For SHA-256 and SHA-512, no collision has ever been found and finding one is considered computationally infeasible.

If hashing is one-way, how are passwords verified?

You hash the input the user provides at login and compare it to the stored hash. If they match, the password is correct. You never store the original password.

What is a salt and why does it matter for password hashing?

A salt is a unique random value added to the password before hashing. It ensures that two users with the same password get different hashes, and prevents precomputed rainbow table attacks.

Related cheatsheetsAll cheatsheets →
Related guidesAll guides →