Encoding vs Encryption vs Hashing: Which One Your Data Actually Needs
Encoding, encryption and hashing all turn readable data into something that looks unreadable, which is why they are confused so often — and why the confusion ends up in security incident reports. The useful way to tell them apart is not how the output looks but what question each one answers: can anyone reverse it, can only a key-holder reverse it, or can nobody?
The one-line distinction
- Encoding changes the representation so data survives a channel. Anyone can reverse it; no secret exists.
- Encryption hides data from everyone who lacks a key. The key-holder can reverse it.
- Hashing produces a fixed-length fingerprint. Nobody can reverse it; you can only compute it again and compare.
If a design needs confidentiality, only encryption provides it. If a design needs to check that something is unchanged or matches, hashing is the tool. If a design needs data to pass through a system that would otherwise corrupt it, that is an encoding problem, and adding secrecy to it achieves nothing.
Encoding: making data fit a channel
Channels have rules. URLs reserve ?, & and /. HTML treats < as the start of a tag. Email and JSON were designed around text, not arbitrary bytes. Encoding translates data into a form those rules accept.
Pick the encoding by destination: URL encoding for query strings and path segments, HTML entity encoding for text placed into markup, and Base64 for binary data inside text formats such as JSON, data URIs and email attachments.
The recurring mistake is using the wrong encoding for the context. URL-encoding a value that ends up inside an HTML attribute, or HTML-escaping a value inserted into JavaScript, leaves the real injection risk in place. The encoding must match the place the data lands, and it must be applied at that point rather than once at input time.
Encryption: controlling who can read it
Encryption is the only one of the three that protects confidentiality. Use it for data in transit (TLS handles this for HTTP) and for sensitive data at rest — personal records, tokens, backups.
Two practical rules cover most of what goes wrong. Use a vetted library and a modern authenticated mode such as AES-GCM or ChaCha20-Poly1305, rather than assembling primitives yourself; authenticated modes detect tampering as well as hiding content. And treat the key as the real secret: encryption with a key stored beside the ciphertext, committed to a repository or shipped in client-side code is encoding with extra steps.
Hashing: proving something without revealing it
A cryptographic hash such as SHA-256 maps any input to a fixed-size digest, and changing one bit of input changes the digest completely. That makes it ideal for detecting change — deduplicating files, cache keys, and verifying downloads against a published checksum. The hash generator computes SHA digests in the browser so you can watch that avalanche effect for yourself.
A plain hash is a poor choice when the input is guessable. If the possible inputs are small — phone numbers, dates of birth, common passwords — an attacker hashes every candidate and matches the results. Passwords need a deliberately slow, salted algorithm, a topic covered in our guide to password strength.
Where the categories combine
HMAC mixes a secret key into a hash. The output proves both that the data is unchanged and that it was produced by someone holding the key. Webhook signatures and many API request-signing schemes rely on it.
Signed tokens combine all three. A typical JWT is Base64URL-encoded, signed with an HMAC or a private key, and not encrypted at all — so anyone holding the token can read its claims. The JWT decoder makes that visible instantly, which is a useful reminder never to put anything confidential in a token's payload unless you are using an encrypted format.
Choosing in practice
| You need to… | Use |
|---|---|
| Put binary data inside JSON or a URL | Encoding |
| Show user text safely inside HTML | Context-specific output encoding |
| Keep data secret from anyone without a key | Authenticated encryption |
| Check a file was not altered or corrupted | Hash |
| Prove a message came from a key-holder | HMAC or digital signature |
| Store passwords | Slow salted password hash |
Red flags in code review
- A variable called
encryptedthat holds Base64. - Obfuscating an API key by encoding it in client-side code.
- Hashing low-entropy identifiers and calling them anonymised.
- Decrypting on the client with a key that ships in the bundle.
- A token payload containing personal data on the assumption nobody can read it.