Why identical-looking text produces different hashes

Inspect UTF-8 bytes, Unicode normalisation and line endings before comparing text digests across applications.

Two pieces of text can look identical and produce different hashes because the bytes differ. A line ending, invisible space, Unicode representation or byte-order mark can change the digest. Hashing is exact; visual similarity is a different question.

When a text hash disagrees across applications, inspect the transformation pipeline before blaming the algorithm. Determine which characters were present, how they were encoded and whether any layer trimmed, normalised or reformatted them. Then compare the actual byte sequence.

Define the input as UTF-8 bytes

The text hash tool encodes the exact entered text with TextEncoder and computes the selected digest. TextEncoder uses UTF-8. Leading spaces and line breaks are part of the input; the tool does not intentionally trim them before hashing.

A cryptographic digest operates on bytes, not abstract words. If another tool hashes a UTF-16 file, a legacy-encoded string or a complete file including a byte-order mark, its input differs from this UTF-8 text conversion. Matching algorithm names do not compensate for different inputs.

Record both character representation and byte length. JavaScript string length counts UTF-16 code units, which is not the same as UTF-8 byte length or user-perceived character count. An emoji can occupy several bytes even though it appears as one visible symbol.

Distinguish equivalent-looking Unicode sequences

The character é can be represented as one precomposed code point or as an e followed by a combining acute accent. These sequences can render similarly but encode to different UTF-8 bytes. Without a normalisation step, their hashes differ.

Precomposed:        U+00E9       UTF-8: C3 A9
Combining sequence: U+0065 U+0301 UTF-8: 65 CC 81

text.normalize('NFC')

NFC can produce a defined normal form for suitable text comparisons, but do not add normalisation blindly. A protocol may require the original bytes, especially for signatures or file integrity. Changing representation before verification can make a correct signed message fail or alter the meaning of an exact-byte contract.

If your application defines normalised text hashing, document the form and apply it consistently before encoding on every side. Keep that result distinct from a raw-file checksum. The normalisation choice is part of the algorithm's input definition.

Common sources of text-hash disagreement
DifferenceExampleCheck
Line endingsLF versus CRLFInspect bytes at every line boundary
Trailing newlineabc versus abc followed by LFCheck editor and command output behaviour
Unicode formPrecomposed versus combining accentsCompare code points and normalisation contract
WhitespaceSpace versus non-breaking spaceDisplay escaped or hexadecimal bytes
EncodingUTF-8 versus UTF-16Confirm the byte encoder
File metadata bytesByte-order mark at the startCompare file hashing with pasted-text hashing

Check line endings and the final newline

Unix-style text commonly uses LF, while Windows text often uses CRLF. A two-line document can look the same in an editor while containing different bytes at each boundary. Git settings, editors and transfer tools can convert line endings without changing the visible wording.

A trailing newline is another frequent difference. Some command-line utilities append a newline when printing a value, while a browser input may not contain one. Hashing the command's output can therefore include a byte the developer did not intend.

Use a byte-aware comparison or a trusted command that accepts exact input. Avoid shell constructions whose quoting or newline behaviour is unclear. The goal is to verify the message bytes, not to find a sequence of trimming operations that happens to produce a desired digest.

Reproduce the familiar abc test correctly

The SHA-256 digest of the three ASCII bytes for abc is a well-known test vector. The UTF-8 encoding is the same three bytes: 61 62 63 in hexadecimal. No space, quote or newline belongs in that input.

Input bytes: 61 62 63
SHA-256:
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

Enter abc into the text hash tool and compare the full digest. Then add a newline and observe that the digest changes. This demonstrates input sensitivity without requiring an explanation based on browser identity or randomness.

For a cross-language test, create those exact bytes in both implementations. Compare byte length and hexadecimal input before comparing the hash. If the bytes match and a standard implementation still disagrees, then investigate algorithm selection and output representation.

Keep digest bytes separate from their display

A digest can be displayed as hexadecimal or Base64. The underlying bytes can be identical while the strings look different. Hex letter case also changes the display without changing the represented value. Confirm representation before calling two digests inconsistent.

SHA-256 produces 32 digest bytes, commonly shown as 64 hexadecimal characters. SHA-384 and SHA-512 produce longer outputs. Selecting a different algorithm changes the digest definition; truncating a longer string is not the same as computing a shorter standard digest.

Compare complete values after a deliberate representation conversion. Do not compare only prefixes or count how many characters differ. Cryptographic hashes do not encode a useful measure of text similarity in the number of matching output characters.

Do not assume equivalent JSON has identical text

JSON objects can be serialised with different whitespace or member order while representing equivalent application data. Hashing the raw JSON text preserves those differences. A pretty-printed version and a compact version usually have different bytes.

If a protocol signs raw request bytes, retain those bytes before parsing and reserialising. If it signs a canonical representation, follow the specified canonicalisation algorithm exactly. Inventing a rule such as sort keys and remove spaces can miss numeric, Unicode or duplicate-key issues.

The JSON validator can help inspect syntax, but formatting output is a transformation. Do not pass reformatted output into a raw-byte signature check and expect it to match the original request.

Do not use a fast text digest as password storage

General-purpose hashes such as SHA-256 are designed to be fast. Password storage needs a suitable password-hashing design with salts and work factors appropriate to the system. Hashing a password once in a browser does not make it safe to store as a login verifier.

Likewise, a plain digest does not authenticate who created a message. Anyone can compute a new digest after changing the text. Use a suitable HMAC or digital signature when the task requires message authenticity, with a defined key trust and byte contract.

Keep these use cases separate in documentation: file consistency, text comparison, password verification and message authentication have different requirements. A tool that calculates a digest does not choose the security protocol for you.

Create a byte contract for integrations

Specify text encoding, normalisation, newline handling, whitespace rules and digest representation in the integration documentation. Include at least one non-ASCII test vector and one value containing a line break. These examples catch assumptions hidden by simple English words.

Preserve the original input while investigating a mismatch. Show code points or hex bytes in a controlled diagnostic, with sensitive content redacted as needed. A screenshot of rendered text is not enough to reveal invisible differences.

Once both sides agree on bytes, keep a stable regression vector. Test the protocol boundary rather than mirroring one implementation's current output blindly. A shared mistake can make two systems agree while still violating the documented contract.

Make invisible spaces visible in a fixture

Compare ordinary space U+0020 with non-breaking space U+00A0 in a short synthetic phrase. They can look similar but have different UTF-8 encodings. Record both code points and byte lengths, then calculate the digests. This fixture is useful when text arrives from rich-text editors or copied web pages, where visual inspection alone can miss the character that changed the result.

Frequently asked questions

Why do identical-looking strings hash differently?

They can contain different Unicode sequences, whitespace or line endings. Hashes operate on encoded bytes. Compare code points and UTF-8 bytes before deciding the algorithm is wrong, and apply normalisation only if the protocol explicitly requires it.

Does the tool trim my input?

The text-hashing operation preserves the entered value before UTF-8 encoding. Spaces and newlines affect the result. Browser text controls still have their own input representation, so use file hashing when the requirement is to verify an existing file's exact bytes.

Is a file hash the same as pasting its text here?

Not necessarily. Reading and pasting can change encoding, line endings or byte-order marks. File hashing measures the saved file bytes. Pasted-text hashing measures the browser string after UTF-8 encoding. Choose the operation that matches the evidence you need.

Can a hash show how similar two texts are?

A cryptographic digest is for exact consistency checks, not semantic similarity. A tiny input change can alter the whole output. Use a text diff or an explicitly designed similarity method when you need to understand the size or meaning of a change.

Should I normalise every password before hashing?

Follow the authentication system's explicit input contract and appropriate password guidance. Silent changes can make users' secrets behave unexpectedly. This general text digest tool is not a password-storage implementation and should not be used as one.

Why does Base64 look different from hexadecimal?

They are different encodings of bytes. Decode the representation or convert it deliberately before comparing. Keep the algorithm name and output format with every digest so another system knows what the string means.

What is the fastest useful mismatch check?

Compare algorithm, byte length, final newline, line endings and encoding first. Then inspect Unicode normalisation and invisible characters. Those concrete checks resolve many disagreements without changing the security protocol or guessing at the expected output.

Sources and further reading

50 useful tools · ↑ ↓ to navigate · Enter to open · Esc to close