Small SEO Tools

Why SHA-256 Hashes Differ for Text That Looks the Same

Two pieces of text can look identical while producing different SHA-256 hashes. A trailing newline, an invisible space or a different Unicode sequence can change the bytes being hashed. Start by comparing the input bytes and settings before assuming the hashing tool is wrong.

This guide uses the SHA-256 Generator to reproduce those differences with short examples. The tool hashes text encoded as UTF-8. Its text box is useful for investigating strings; it is not a file-upload checksum tool.

First match the algorithm and output format

  1. Open the SHA-256 Generator.
  2. Set Algorithm to SHA-256.
  3. Set Output format to Hexadecimal.
  4. Leave Uppercase hex output unchecked.
  5. Enter abc in Text to hash, without spaces or a final line break, and select Generate hash.

The lowercase hexadecimal result is:

ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

The tool shows three UTF-8 bytes and a 256-bit digest. SHA-256 produces 32 digest bytes; writing each byte as two hexadecimal digits gives a 64-character hex string. MDN documents the algorithm and digest sizes in its SubtleCrypto.digest reference.

Uppercase and lowercase hex letters can represent the same bytes. Base64 is another representation, so a Base64 digest will not look like a hexadecimal digest even when the input and algorithm match. Compare like with like before troubleshooting the text.

Reproduce a mismatch caused by one newline

Place the cursor after abc and press Enter once. Generate the hash again. The input now contains four UTF-8 bytes, and its hash is:

edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb

The first input contains only abc. The second also contains an actual line-feed character after the letter c. In programming notation that second value is often written "abc\n". Typing a backslash followed by the letter n into the tool is different from pressing Enter.

The tool does not trim the text before hashing. An extra space, tab or line break therefore matters. Inspect the start and end of a pasted value, especially if it came from a terminal, spreadsheet or formatted document.

Text-area input is not a byte-for-byte view of a file: browsers can normalize line endings. To verify a downloaded file, use a checksum utility that reads the original file bytes. Pasting its visible contents into a text box is not an equivalent check.

Check Unicode when visible text still matches

The word café can be represented with a single precomposed é, or with an e followed by a combining acute accent. Here are two JavaScript-style representations of those sequences:

"caf\u00e9"    // precomposed accented letter
"cafe\u0301"   // e plus a combining accent

These are explanatory escape sequences, not strings to paste literally into the tool. When entered as their actual Unicode characters, the first takes five UTF-8 bytes and the second takes six. They produce different hashes in the generator even though they may render the same way.

The generator uses the browser’s TextEncoder, which produces UTF-8 bytes, and does not normalize the input first. See MDN’s TextEncoder documentation for that encoding behavior.

Unicode normalization can convert canonically equivalent sequences to a shared form. For example, JavaScript’s text.normalize("NFC") can resolve this particular composed-versus-decomposed difference. Apply it only when both sides of your workflow agree to hash normalized text. MDN’s normalization guide explains the available forms and their effects.

Do not silently normalize, trim or change capitalization when checking an existing checksum or an exact signed payload. That changes the input rather than explaining the expected result.

Separate a Base64 digest from Base64 text

If you select Base64 in the hash generator, you are encoding the digest bytes as Base64. You are not encoding the original message directly. A Base64 encoding of abc and a Base64 encoding of its SHA-256 digest are different values for different purposes.

For reversible text encoding, follow the UTF-8 Base64 encoding and decoding guide. For a hash comparison, keep the digest algorithm and representation consistent across both tools.

A practical mismatch checklist

  1. Identify the input. Are both systems hashing text, the original file bytes, or a larger payload containing the text?
  2. Match settings. Confirm SHA-256 on both sides and compare the same output representation.
  3. Count bytes. Different byte counts prove the inputs differ; equal counts do not prove they match.
  4. Inspect boundaries. Check for a final newline, leading space or copied quotation marks.
  5. Check encoding and Unicode. Confirm UTF-8 and any agreed normalization rule.
  6. Retest a known short input. Use the abc result above to separate a settings issue from a data issue.

A matching digest is useful for comparison, but it does not by itself prove who created the data. If your goal is to verify a sender, establish a trusted authentication method as well as the exact bytes to be checked.