~/guides/-guides-hash-functions-explained-
guides · Encoding

Hash Functions Explained: MD5, SHA-1, SHA-256

Practical differences, security tradeoffs, and migration guidance for common hash algorithms.

last updated · June 1, 2026by @vultio

What hash functions are actually for

Hash functions turn input data into a deterministic fixed-length fingerprint. The important property is not that the output looks random, but that the same input always produces the same digest while even a tiny change in the input produces a completely different-looking result.

In real engineering workflows, hashes are used for integrity checks, deduplication, content-addressed storage, cache keys, build artifact verification, and digital-signature pipelines. They are not a reversible encoding layer and they are not a substitute for encryption.

MD5, SHA-1, and SHA-256 in one practical table

AlgorithmDigest sizeUse todayRisk level
MD5128-bitLegacy checksums onlyUnsafe for security-sensitive use
SHA-1160-bitLegacy compatibility onlyCollision-broken for trust decisions
SHA-256256-bitModern defaultStrong baseline for integrity and signatures

Why MD5 and SHA-1 are no longer safe defaults

MD5 and SHA-1 are still common in old documentation because they were once widely deployed, but both have known collision weaknesses. A collision means two different inputs can be crafted to produce the same hash. That breaks the trust model for signatures, certificate-like verification, and any system that assumes the digest uniquely identifies the content.

In practice, you may still encounter MD5 in file checksums or ancient APIs and SHA-1 in legacy git-era references, but new systems should not choose them for security decisions. If you only need a modern, boring, safe default, SHA-256 is the usual answer.

When SHA-256 is the right answer

Verifying downloaded files or build artifacts before deployment.
Creating stable fingerprints for API payload snapshots or deduplicated storage.
Using a modern hash inside signature or token-verification systems when the protocol expects SHA-256.
Replacing outdated MD5 or SHA-1 usage in internal tooling without changing the overall workflow too much.

Hashing vs encryption vs password storage

These topics get mixed together constantly. Hashing is one-way and useful for fingerprints. Encryption is two-way and useful when data must be recovered later. Password storage is a separate problem again: you should not store raw passwords with plain SHA-256 and call it done.

For passwords, the standard advice is to use a slow password hashing function such as bcrypt, scrypt, or Argon2, ideally with library defaults and salts handled by the framework. A fast general-purpose hash like SHA-256 is great for integrity, but a poor choice for password storage on its own.

Migration advice for legacy systems

  1. Inventory where the old hash is used. Checksums, signatures, API compatibility, or passwords all require different migration plans.
  2. Separate compatibility from security. You may keep reading MD5 or SHA-1 for old records while writing new material with SHA-256.
  3. Document the change clearly. Hash migrations break silent assumptions in clients, tests, and operations scripts if the output length or expected value changes.
  4. Do not rewrite history blindly. For archives and old references, preserving legacy digests alongside stronger new ones is often safer than replacing them in place.

Common mistakes developers make with hashes

Using MD5 because it is shorter

Output length is not the reason to choose a security primitive. Convenience is a poor trade for collision weakness.

Calling Base64 a hash

Base64 is reversible encoding. Hashes are one-way fingerprints. They solve different problems.

Hashing secrets instead of generating them properly

A weak secret hashed with SHA-256 is still a weak secret. Entropy must exist before hashing adds any value.

Using one sample digest as proof of security

A hash function can work mechanically while still being the wrong algorithm for signatures or passwords.

How to choose quickly in practice

If you need a modern default for integrity checks, downloaded files, signed payload support, or content fingerprints, SHA-256 is usually the boring correct answer. Reach for legacy hashes only when compatibility forces you to read or compare old material.

If the problem is password storage, stop and use a dedicated password hashing function instead. That distinction is where many “we use hashing already” conversations go wrong.