💻 Coding

Multi-Hash Generator

Type or paste text and instantly see its MD5, SHA-1, SHA-256, SHA-384, and SHA-512 hashes, computed live in your browser.

About the Multi-Hash Generator

Type in some text and get back MD5, SHA-1, SHA-256, SHA-384, and SHA-512 digests all at once, computed with the browser's built-in Web Crypto API wherever possible. MD5 is the odd one out since it isn't part of that API, so it runs on a hand-rolled JavaScript implementation instead, but the result stays entirely on your device either way.

Why MD5 has to be implemented by hand at all

The Web Crypto API deliberately doesn't include MD5 as an option, that's not an oversight, browser vendors excluded it on purpose because MD5 has been cryptographically broken for years, with practical collision attacks (two different inputs producing the same hash) demonstrated repeatedly since the mid-2000s. The API's design philosophy is to expose only currently-recommended algorithms rather than a general-purpose toolbox that includes known-weak ones. That's exactly why this tool ships a full, hand-written JavaScript implementation of the algorithm as specified in RFC 1321, it's the only way to offer MD5 output at all in a browser that intentionally won't provide it natively. Worth noting: "cryptographically broken" specifically means MD5 is unsafe for security purposes like password hashing or digital signatures, it remains genuinely useful for non-security tasks like verifying a file download completed without corruption or matching against a legacy system that still specifies MD5 checksums.

Why the message gets padded in a very specific way before hashing

Before processing, the input bytes get a single 0x80 byte appended, then zero bytes until the total length is 56 modulo 64, then the original message's bit-length gets appended as the final 8 bytes. This exact padding scheme, part of the broader Merkle–Damgård construction that MD5 and many other hash functions are built on, exists so the algorithm always has a clean multiple of 64 bytes to work through, and critically, it bakes the original message's length directly into what gets hashed. Two messages that happen to be identical except for trailing padding would otherwise risk colliding, encoding the actual bit length as part of the input closes off that particular class of ambiguity.

The four-round mixing structure that produces the avalanche effect

MD5 processes each 64-byte chunk through 64 total operations organized into four rounds of 16 each, and each round applies a different bitwise mixing function, you can see this directly in the code's i < 16, i < 32, i < 48 branches, each computing F differently using a distinct combination of AND, OR, and XOR across the working variables. Combined with a rotate-left operation and a different fixed shift amount at each step, this repeated mixing is what produces the avalanche effect central to any good hash function, flipping a single bit anywhere in your input should statistically flip roughly half the bits in the final output, making the output for even barely-different inputs look completely unrelated.

Why you'll see | 0 scattered through the arithmetic

MD5's math is defined to operate on 32-bit values with arithmetic that wraps around on overflow, the way it would in C. JavaScript numbers don't naturally behave that way, they're floating-point by default and don't wrap at 32 bits on their own. The | 0 you'll spot after several additions is a common technique that forces the result back into a 32-bit signed integer by performing a bitwise OR with zero, which as a side effect discards anything beyond 32 bits and restores the correct wraparound behavior the algorithm actually depends on.

Why SHA-1 is still offered even though it's also considered broken today

SHA-1 was formally demonstrated to be practically breakable in 2017 (the "SHAttered" collision attack), and it's no longer recommended for any new security-sensitive use, yet it's still part of the Web Crypto API and included here. That's purely for compatibility and reference, plenty of legacy systems, git's internal object hashing, and older verification workflows still use or expect SHA-1 output, so having it available for comparison or legacy interoperability is still useful even though it shouldn't be your choice for anything security-critical going forward. The SHA-2 family, SHA-256, SHA-384, and SHA-512, are the currently recommended options here for anything where cryptographic strength actually matters.

Frequently Asked Questions

Why doesn't the browser's built-in Web Crypto API support MD5?

Browser vendors deliberately excluded it, since MD5 has been cryptographically broken for years, with practical collision attacks demonstrated repeatedly. The API only exposes currently-recommended algorithms, so this tool includes a full hand-written JavaScript implementation of MD5 specifically to still offer it.

Is MD5 still useful for anything if it's cryptographically broken?

Yes, for non-security purposes. "Broken" means it's unsafe for things like password hashing or digital signatures. It remains genuinely useful for verifying file download integrity, deduplication checksums, or compatibility with legacy systems that specify MD5, none of which require collision resistance.

Why is the original message's bit-length appended during MD5 padding?

Encoding the exact bit length into the padded message, as part of the Merkle–Damgård construction MD5 is built on, closes off a class of ambiguity where two different messages might otherwise produce identical padded input. It's a structural requirement of how MD5 and similar hash functions are designed.

What causes a tiny change in input to produce a completely different hash?

MD5 runs 64 operations across four rounds, each applying a different bitwise mixing function combined with rotation. This repeated mixing produces the avalanche effect, where flipping even one bit of input statistically flips roughly half the output bits, making similar inputs produce unrelated-looking hashes.

Why does the MD5 code use "| 0" after arithmetic operations?

MD5 requires 32-bit arithmetic that wraps around on overflow, but JavaScript numbers don't naturally wrap at 32 bits. Applying | 0 (bitwise OR with zero) forces the result back into a 32-bit signed integer, restoring the wraparound behavior the algorithm depends on.

Should I use SHA-1 for security-sensitive purposes?

No, SHA-1 was practically broken in 2017 and isn't recommended for new security-critical use. It's included here mainly for compatibility with legacy systems that still expect it. For anything where cryptographic strength matters, use SHA-256, SHA-384, or SHA-512 instead.