SHA1 Hash Generator

Hash text or a file, read the digest as five 32-bit registers instead of one long string, and switch on git mode to reproduce the object ID your repository would give the same content.

SHA-1 digest workbench

Hashed in this tab, nothing uploaded

Two different files with the same SHA-1 have been built and published since 2017. Use this for object IDs, legacy checksums and old system compatibility. For signatures, passwords or anything an attacker gains from forging, move to SHA-256.

SHA-1 digest
Type something or drop a file to see a digest.
Waiting for input.
Input length0 bytes
512-bit blocks1
Padding added64 bytes
Nothing to compare yet.

SHA-1 lost its security argument in 2017 and still names every object in your git repository

Both statements hold at once, and the reason is worth understanding before you decide whether a SHA-1 in your codebase is a finding or a non-issue. Collisions against SHA-1 are real, published and reproducible on rented hardware. Git ships collision detection and treats the digest as a name rather than a promise. Where your own use sits between those poles decides everything.

Reading the 40 characters as five registers

SHA-1 keeps a working state of five 32-bit words, named h0 through h4 in FIPS 180-4. They start at fixed constants, every 512-bit block of your message stirs them through 80 rounds, and the final values written end to end in big-endian order are the digest. The register strip above splits the output on those boundaries so the structure stays visible.

Hash the word abc and the five registers read a9993e36, 4706816a, ba3e2571, 7850c26c and 9cd0d89d. That is the test vector printed in the FIPS specification, so a mismatch anywhere in your own implementation shows up on the very first case.

160 bits sounds close to the 256 of its successor. The gap matters more than the ratio suggests: a birthday attack works over half the digest width, which puts the theoretical collision cost at 280 for SHA-1 against 2128 for SHA-256. Cryptanalysis then pulled the real figure well below 280.

Padding, blocks, and why an empty input still produces a digest

SHA-1 never hashes your bytes on their own. It pads the message first, following a rule inherited from the Merkle-Damgard construction:

The facts row above reports the block count and padding size for whatever you typed. Feed it 55 bytes and the padding fits inside a single block. Feed it 56 and a second block appears, because the 9 bytes of mandatory padding no longer fit. This is the whole reason an empty string hashes to da39a3ee5e6b4b0d3255bfef95601890afd80709 rather than to nothing: zero bytes of message still leave one padded block to process.

The 64-bit length field also caps the algorithm at 264 bits of input, roughly 2 exabytes. No practical file reaches it.

What broke, precisely

Two results ended SHA-1 as a signature hash, and they differ in kind.

ResultYearCostWhat it gives an attacker
SHAttered, by CWI Amsterdam and Google2017About 6,500 CPU years plus 100 GPU years, run in parallelTwo PDF files with different visible content and one identical SHA-1
Chosen-prefix collision, by Leurent and Peyrin2019 and 2020Around 45,000 US dollars of rented GPU timeTwo files starting with different attacker-picked content and still colliding, which is what forging a certificate or a PGP identity needs

The second result is the serious one. An identical-prefix collision needs both documents built by the attacker from the start. A chosen-prefix collision lets an attacker take content someone else insists on, such as a real certificate subject or a signed message header, and construct a colliding partner around it. Every attack in the wild people worried about needed exactly that step.

Preimage resistance is a separate property, and it holds. Nobody has recovered an input from a SHA-1 digest, and no published attack comes close. Short inputs still fall to a dictionary or a rainbow table, which is a statement about password entropy rather than about SHA-1, and the reason password storage needs bcrypt or Argon2 instead of any raw digest.

Git mode, and the header behind a mismatch

Switch on the git checkbox above and the tool stops hashing your input directly. It builds the object git would store:

blob <byte length><NUL><content>

Run echo "hello world" | git hash-object --stdin and git returns 3b18e512dba79e4c8300dd08aeb37f8e728b8dad. The content there is 12 bytes, because echo appends a newline, so the bytes fed to SHA-1 are blob 12, a zero byte, then hello world and that newline. Drop the newline with echo -n and the ID changes to 95d09f2b10159347eece71399a7e2e907ea3df4f. Neither matches sha1sum on the same content, which returns the plain digest with no header at all.

This explains a question that comes up constantly: a file's checksum and its git object ID are different numbers for the same bytes, and neither one is wrong. Commits, trees and tags use the same scheme with their own type words and their own serialized bodies, so this page covers blobs only.

Where SHA-1 is banned now

Where it still earns its keep

The dividing line is whether an attacker gains anything by finding two inputs with one digest. Accidental collisions do not happen at this width. Deliberate ones are for sale.

Reproducing this outside the browser

EnvironmentCommand or call
Linux shellprintf '%s' 'abc' | sha1sum
macOS shellprintf '%s' 'abc' | shasum -a 1
OpenSSLopenssl dgst -sha1 report.pdf
PowerShellGet-FileHash -Algorithm SHA1 report.pdf
PHPsha1('abc') for text, sha1_file($path) for a file
Pythonhashlib.sha1(b'abc').hexdigest()
Nodecrypto.createHash('sha1').update('abc').digest('hex')
Git blob IDgit hash-object -t blob file.txt

Use printf rather than echo when comparing against this page. Plain echo adds a trailing newline on most shells, and that one byte rewrites the entire digest.

Where this tool stops

Questions people ask after a SHA-1 turns up in an audit

Compatibility, git object IDs and the difference between a collision and a break.

Is SHA-1 broken, or only discouraged?

Broken for anything resting on collision resistance. A chosen-prefix collision was demonstrated in 2020 for roughly 45,000 US dollars of rented GPU time, which puts forged signatures and certificates inside reach of a funded attacker. Preimage resistance is untouched, so nobody recovers your input from a digest. That split is why SHA-1 is gone from TLS certificates and code signing while git still names objects with it.

Why does my git object ID differ from sha1sum on the same file?

Git hashes a header along with the content. It builds the word blob, a space, the byte length, a zero byte, then the file bytes, and hashes all of it. A plain sha1sum hashes the bytes alone. Tick the git checkbox above and the tool shows the exact preimage it builds, which lines up with git hash-object.

What are h0 to h4 in the register strip?

SHA-1 keeps five 32-bit words of internal state. They begin at fixed constants from FIPS 180-4, each 512-bit message block updates them across 80 rounds, and the final five values written back to back in big-endian order form the 40 hex character digest. Splitting the output on those boundaries is a display choice, so copying still gives you the full digest.

Is there any way to recover the original text from a SHA-1 hash?

No. SHA-1 discards information, and reversing it has no known method. Short or common inputs are a different matter: a password or a single English word falls to a wordlist in seconds, since an attacker hashes candidates until one matches. That is guessing rather than reversing, and it is why password storage needs bcrypt or Argon2 rather than any raw digest.

Should I still use SHA-1 for file checksums?

For catching a corrupted download or a truncated transfer, yes. Random corruption never lands on a matching 160-bit digest. For confirming a release file is the one the vendor built, no. An attacker who controls both files produces a matching pair, so publish and verify with SHA-256 when the threat includes deliberate substitution.

Why is an empty input still giving me a hash?

Padding. SHA-1 appends a 1 bit, then zero bytes, then a 64-bit length field, so even zero bytes of message leave one full 512-bit block to process. The result is da39a3ee5e6b4b0d3255bfef95601890afd80709, a constant worth recognising. Seeing it in a log usually means a variable arrived empty rather than the hash failing.

Does the file I drop here get uploaded?

No. The file is read through the browser FileReader API in 4 MB slices and hashed in the tab. Nothing in the hashing path makes a network request. The CryptoJS library loads from a CDN when the page opens, so the first visit needs a connection and the tool works offline after that.

Do the collision attacks affect HMAC-SHA1?

Not in practice. HMAC security rests on a different property than collision resistance, and no forgery against HMAC-SHA1 has been published. TOTP codes under RFC 6238, AWS Signature Version 2 and OAuth 1.0a all still specify it. Scanners flag SHA-1 wherever they see it, so expect to explain the distinction if you keep it.

What should I migrate to?

SHA-256 for almost everything, since it is the widest-supported member of the SHA-2 family and no attack threatens it. SHA-512 runs faster on 64-bit CPUs for large inputs. SHA-3 uses a completely different internal design and suits anyone who wants distance from the Merkle-Damgard structure both MD5 and SHA-1 share. Password storage is the exception and belongs on bcrypt, scrypt or Argon2.

Why do my uppercase and lowercase digests look like different values?

They are the same 160 bits written two ways. Hex has no case, so tools disagree by convention: sha1sum prints lowercase, PowerShell Get-FileHash prints uppercase. String comparisons treat them as different, which is a frequent cause of a checksum check failing on identical files. Normalise the case before comparing, and use the format buttons above to match whichever side you are checking against.