Decode & Encode

Transform text between encoding formats instantly in your browser.

B64

Base64

Encode or decode Base64 strings. Commonly used for binary data in JSON, APIs, and email.

Output

What text encoding actually does

Encoding is the process of mapping characters to a specific byte representation so they can safely travel through systems that only accept a restricted character set. It is not encryption. Anyone who knows the encoding scheme can decode the output β€” the goal is transport safety, not secrecy.

Each format above solves a different practical problem. Picking the right one matters: the wrong encoding can quietly corrupt data, break URLs, or introduce subtle security bugs like cross-site scripting.

When to use each format

Base64

Base64 represents binary data using 64 printable ASCII characters (A–Z, a–z, 0–9, +, /, with = padding). Use it when you need to embed binary data in a text-only context: images in data URIs, file uploads in JSON payloads, credentials in HTTP Basic auth, or attachments in email MIME bodies. Base64 inflates size by about 33%.

A common variant, Base64URL, swaps + and / for - and _ so the output is safe to drop into URLs or filenames. JWTs use Base64URL, not standard Base64.

URL encoding (percent-encoding)

URL encoding replaces reserved characters with % followed by their two-digit hex byte value. Use it on individual components of a URL β€” query string values, path segments containing spaces or /, fragments β€” not on the whole URL at once. For example, the space in hello world becomes %20, and & inside a query value becomes %26 so it isn't mistaken for a parameter separator.

HTML entity encoding

HTML entities escape characters that would otherwise be interpreted as markup: < becomes &lt;, & becomes &amp;, and so on. Anywhere untrusted text gets rendered into an HTML page, it should be entity-encoded first. Failing to do so is the root cause of most stored XSS vulnerabilities.

Hex

Hexadecimal encoding writes each byte as two characters from 0–9 and a–f. You'll see it in hash outputs, memory dumps, binary file inspection, and cryptographic key displays. It doubles the size of the input but is easier for humans to read byte-by-byte than Base64.

Binary

Binary encoding writes each byte as eight 0/1 characters. It's rarely used for real transport (it's 8Γ— larger than the original), but it's useful for teaching, for visualizing bit-level operations, and for low-level debugging.

ROT13

ROT13 rotates each Latin letter by 13 positions: A↔N, B↔O, and so on. It is a trivial substitution cipher, historically used on Usenet to obscure spoilers. It has no security value. Non-letters pass through unchanged.

Common pitfalls

  • Base64 is not encryption. Anyone can decode it in one step. Never use Base64 alone to protect credentials or tokens.
  • Encode components, not whole URLs. Running encodeURIComponent on an entire URL mangles the :// and ?. Encode each query value individually.
  • Entity-encode before rendering, not before storing. Store the raw string; encode at the point of output. That way the same data can render safely in HTML, JSON, or CSV contexts.
  • Watch padding. Standard Base64 may end with = or ==. Some implementations strip it; others require it. Base64URL usually omits it.
  • Character set confusion. Hex and Base64 require ASCII; feeding them UTF-8 multi-byte sequences works, but round-trip through systems that assume Latin-1 can corrupt non-ASCII text.

FAQ

Is Base64 secure for passwords or API keys?

No. Base64 is not encryption. It is reversible with no key. Treat a Base64-encoded secret exactly like the plaintext secret.

Why does my Base64 output end in =?

Base64 encodes in groups of three bytes. If the input length isn't a multiple of three, the encoder adds = padding so the output length is a multiple of four. One missing byte produces one =; two missing bytes produce ==.

What's the difference between encoding and escaping?

In practice the terms overlap. "Encoding" usually refers to a complete byte-to-character transform (Base64, hex). "Escaping" usually refers to selectively replacing only the problematic characters for a specific context (HTML entities, backslash escapes in strings).

Does DevDecoder send my text to a server?

No. All six tools run entirely in your browser via plain JavaScript. The input never leaves your device. Inspect the source or open DevTools Network tab β€” there are no encode/decode network requests.

Hash Generator

Generate cryptographic hashes from any text. All hashing runs locally in your browser.

#

Generate All Hashes

Type or paste text below to instantly compute MD5, SHA-1, SHA-256, SHA-384, and SHA-512 hashes.

MD5
SHA-1
SHA-256
SHA-384
SHA-512

What a cryptographic hash is

A cryptographic hash is a one-way function that turns any input β€” a string, a file, a message β€” into a fixed-length fingerprint. Two properties matter: the same input always produces the same output, and it is computationally infeasible to recover the input from the output or to find two different inputs that hash to the same value (a "collision").

Hashes are used for file integrity checks, digital signatures, content-addressable storage (like Git commit IDs), deduplication, and as a component inside password hashing schemes. They are not encryption β€” there is no key, and the operation is not reversible.

Picking an algorithm

AlgorithmOutputStatusUse it for
MD5128 bitsBrokenLegacy checksums only. Not for security.
SHA-1160 bitsBrokenLegacy compatibility only (Git, old TLS).
SHA-256256 bitsSecureGeneral-purpose integrity, signatures, blockchain.
SHA-384384 bitsSecureHigher-security signatures, TLS 1.3 cipher suites.
SHA-512512 bitsSecureWhen you want the largest margin, or on 64-bit systems where it can be faster than SHA-256.

MD5 and SHA-1 are broken β€” what does that mean?

Practical collision attacks exist for both. Researchers can produce two different inputs that hash to the same MD5 or SHA-1 digest. That means you cannot trust them when the question is "did this content get tampered with?" or "is this signature authentic?" They are still fine for non-adversarial uses: detecting accidental corruption, sharding data across buckets, or quickly comparing cached values you produced yourself.

Hashing passwords β€” read this first

Never store passwords with a plain SHA-256 or SHA-512. They're designed to be fast, which is exactly the wrong property for password storage. A modern GPU can compute billions of SHA-256 hashes per second, making brute-force cheap.

For passwords, use an algorithm designed to be deliberately slow and memory-hard:

  • Argon2id β€” the current recommendation (winner of the 2015 Password Hashing Competition).
  • bcrypt β€” well-understood, widely supported, still acceptable.
  • scrypt β€” good option if your language has solid library support.
  • PBKDF2 β€” acceptable where FIPS compliance is required, with a high iteration count (600,000+ for SHA-256 as of NIST SP 800-132 updates).

Every one of these applies a per-user random salt automatically and bundles it into the output string. Never roll your own scheme by concatenating salt and password and running SHA-256 β€” you'll miss a detail that matters.

Practical uses for the hashes above

  • File integrity. Compare the SHA-256 of a download against the one published on the vendor's site to detect corruption or tampering.
  • Content addressing. Git commit IDs and IPFS CIDs use hashes so a given piece of content has a deterministic identifier.
  • HMAC signatures. Webhook providers (Stripe, GitHub, Slack) sign payloads with HMAC-SHA-256; you verify by recomputing the hash with the shared secret.
  • Caching keys. Hash a canonical representation of the inputs to produce a stable cache key.
  • Deduplication. Hash chunks of a file to find and skip duplicate blocks in backups or build artifact storage.

FAQ

Can you un-hash a value?

Not directly β€” hashes are one-way. But for short or common inputs, an attacker can simply try every possibility (a "rainbow table" or brute-force lookup). That's why password storage uses salts and slow KDFs, and why a hash of a credit-card number or email address offers very little privacy.

Why does the same input produce different SHA-256 values on different tools?

It shouldn't β€” if it does, something is adding a byte you can't see. Common culprits: a trailing newline from your text editor, a byte-order mark (BOM), or the tool hashing a UTF-16 representation instead of UTF-8. DevDecoder hashes the UTF-8 bytes of the input exactly as entered.

Is SHA-512 always stronger than SHA-256?

It has a larger output, so brute-force is harder. But SHA-256 at 256 bits is already far beyond what's brute-forceable, so the practical security for most uses is the same. Pick based on output size requirements and performance on your target platform, not on "bigger number is better."

What's the difference between a hash and an HMAC?

HMAC combines a hash function with a secret key so the output depends on both the message and the key. A plain hash proves what the content is; an HMAC proves it was produced by someone who holds the key. Use HMAC whenever you need authenticated integrity (webhooks, API signatures, session tokens).

JWT Decoder

Paste a JSON Web Token to inspect its header, payload, and signature. Nothing leaves your browser.

JWT

Decode Token

Enter a JWT (three Base64URL parts separated by dots) to see the decoded contents.

What is a JSON Web Token?

A JWT is a compact, URL-safe way to represent claims β€” small pieces of information β€” transferred between two parties. It's most often used as a bearer token: the client presents it with each request, and the server trusts it because it was signed by an authority the server recognizes.

A JWT is three Base64URL-encoded parts separated by dots:

header.payload.signature

The header says which algorithm was used to sign the token. The payload holds the claims. The signature lets the recipient verify the token wasn't altered.

Standard claims you'll see in the payload

  • iss β€” issuer. Who created this token (e.g. https://auth.example.com).
  • sub β€” subject. Who the token is about, usually a user ID.
  • aud β€” audience. Which service is supposed to accept this token.
  • exp β€” expiration time, as a Unix timestamp. The token is invalid after this.
  • nbf β€” not-before. The token is invalid before this timestamp.
  • iat β€” issued at. When the token was created.
  • jti β€” JWT ID. A unique identifier, useful for revocation tracking.

Anything else is a custom claim: email, roles, tenant_id, or whatever your system needs. Keep custom claims small β€” every request has to carry them.

Signing algorithms

The header's alg field picks the signing scheme. The three common choices:

  • HS256 (HMAC-SHA-256) β€” symmetric. Issuer and verifier share one secret key. Simple, fast, but everyone who can verify can also forge tokens.
  • RS256 (RSA-SHA-256) β€” asymmetric. Issuer signs with a private key; anyone can verify with the public key. Right choice when third parties need to validate tokens.
  • ES256 (ECDSA with P-256) β€” asymmetric, like RS256 but with smaller keys and shorter signatures. A good default if your library supports it.
Never accept alg: none. The "none" algorithm removes the signature entirely. Multiple libraries have shipped bugs where a token with alg: none was accepted as valid. Explicitly pin the expected algorithm in your verification config.

Common JWT mistakes

  • Trusting the decoded payload without verifying the signature. Anyone can produce a Base64URL string that decodes to anything. The signature is what makes the content trustworthy. This decoder inspects only β€” your server must verify.
  • Storing JWTs in localStorage. Accessible to any JavaScript running on the page, so a single XSS bug exposes every user's token. Prefer an HTTP-only, Secure, SameSite cookie.
  • Long-lived access tokens. Once issued, a JWT can't be revoked without extra infrastructure. Use short lifetimes (minutes, not days) and rotate with a separate refresh mechanism.
  • Putting sensitive data in the payload. JWTs are signed, not encrypted. The payload is readable by anyone who has the token. For encrypted tokens, use JWE (JSON Web Encryption).
  • Skipping aud validation. If you issue tokens for multiple services, a token meant for service A should not be accepted by service B.
  • Clock skew. Allow a small leeway (30–60 seconds) when checking exp and nbf so tokens issued near expiry don't fail across slightly out-of-sync machines.

FAQ

Can this tool verify my JWT's signature?

No. Verifying a signature requires the secret key (HMAC) or public key (RSA / ECDSA), and exposing that in the browser would defeat the purpose. DevDecoder decodes the header and payload so you can inspect their contents and check the expiration.

My JWT has weird characters β€” is that normal?

Yes. JWTs use Base64URL (not standard Base64), so you'll see - and _ instead of + and /, and padding = characters are usually stripped. The three sections are separated by dots.

Why is my token rejected even though it hasn't expired?

Check the whole claim set. Common causes: the iss doesn't match what the verifier expects, the aud is wrong, the alg header doesn't match the key type, or nbf is in the future. Enable verbose logging on the verifying library β€” most give a clear reason.

Is it safe to paste a production JWT here?

Decoding happens entirely in your browser. The token is not transmitted. That said: any valid, unexpired production token that's been exposed in a screenshot, log, or browser tab is worth rotating. Treat tokens like passwords.

JSON Formatter

Pretty-print, minify, and validate JSON. All processing stays in your browser.

{}

Format & Validate

Paste raw or minified JSON to pretty-print it, compact it to one line, or check if it is valid.

Output

JSON in one paragraph

JSON (JavaScript Object Notation) is a plain-text format for structured data, originally derived from a subset of JavaScript object literal syntax. A JSON document is one value: an object ({...}), an array ([...]), a string, a number, true, false, or null. It became the dominant interchange format for web APIs because it's easy to read, easy to generate, and supported in every language out of the box.

Strict syntax rules

JSON looks like JavaScript but it's strictly smaller. These rules trip up most people:

  • Keys must be double-quoted strings. {name: "ada"} is valid JavaScript but invalid JSON. It must be {"name": "ada"}.
  • Only double quotes. Single-quoted strings are not JSON.
  • No trailing commas. [1, 2, 3,] is invalid. ECMAScript allows them; JSON does not.
  • No comments. Neither // nor /* */. If you want comments, use JSONC or JSON5 β€” but those are different formats and most strict parsers will reject them.
  • Numbers are decimal only. No 0x hex, no leading +, no trailing decimals like 1., no NaN or Infinity.
  • Strings are UTF-8 sequences of characters, with \n, \t, \", \\, \uXXXX and a few other escapes.

The precision trap with numbers

JSON numbers have no size limit in the spec, but most implementations parse them into a 64-bit float. That means any integer larger than 253 βˆ’ 1 (9007199254740991) can quietly lose precision.

JSON.parse('{"id": 9007199254740993}')
// { id: 9007199254740992 }  // off by one β€” silent corruption

If your API returns big IDs (Twitter snowflake IDs, database bigints, blockchain amounts), serialize them as strings, not numbers. On the client, parse into a BigInt or leave as a string. This is a real production bug, not a theoretical one.

Pretty-print vs. minify

  • Pretty-print adds indentation and newlines. Use it for debugging, log output, and anything a human will read.
  • Minify strips all optional whitespace so the payload is as small as possible. Use it for transport. The two representations are semantically identical β€” parsing either produces the same structure.

Common JSON errors you'll see

  • Unexpected token } in JSON at position N β€” usually a stray trailing comma before the closing brace.
  • Unexpected token ' in JSON β€” single quotes around a key or value. Switch to double quotes.
  • Unexpected end of JSON input β€” the string is truncated. Check that you copied the whole payload, and watch for responses that cut off due to content-length or gzip issues.
  • Unexpected non-whitespace character after JSON β€” two JSON values concatenated, or trailing debug output. Some APIs prefix output with )]}' as an anti-hijacking measure; strip that line before parsing.

FAQ

Can I put comments in JSON?

Not in standard JSON. Some ecosystems use JSONC (JSON with Comments β€” VS Code config files) or JSON5, which are extended dialects that allow comments, trailing commas, and unquoted keys. A standard parser will reject both.

What's the difference between JSON and a JavaScript object?

A JSON document is a string in a specific text format. A JavaScript object is an in-memory data structure. You convert between them with JSON.stringify and JSON.parse. Not every JavaScript object is JSON-serializable β€” functions, undefined, and circular references will be dropped or throw.

Why does my valid JSON fail to validate?

Most often: an invisible character at the start (a UTF-8 BOM, \uFEFF) copied from a file. Remove it, or re-save the file as UTF-8 without BOM.

How do I represent dates?

JSON has no native date type. The de-facto standard is an ISO 8601 string, e.g. "2026-04-18T12:00:00Z". Your parser on both ends handles the conversion to a native date.

Regex Tester

Test regular expressions live against any string. Matches are highlighted inline.

.*

Regular Expression

Enter a pattern and test string. Matches highlight in real time. Supports flags g, i, m, and s.

/ / g
Highlighted Matches

Regex, in less than you'd think

A regular expression is a pattern describing a set of strings. The pattern is matched against a target string, and depending on how you use it, you get either a yes/no answer, a list of matches, or the string with substitutions applied. This tester uses the JavaScript regex engine β€” the same one you'll use in Node and in browsers β€” so the syntax you learn here is the syntax you'll ship.

The building blocks

Literals and metacharacters

Most characters match themselves. A handful have special meaning and must be escaped with a backslash to match literally: . * + ? ^ $ ( ) [ ] { } | \. For example, to match a literal period, write \..

Character classes

  • [abc] β€” any one of a, b, c.
  • [^abc] β€” any character except those.
  • [a-z0-9] β€” ranges.
  • \d, \w, \s β€” digit, word character ([A-Za-z0-9_]), whitespace.
  • \D, \W, \S β€” their negations.
  • . β€” any character except newline (unless the s flag is on).

Anchors

  • ^ β€” start of string (or line, with m).
  • $ β€” end of string (or line, with m).
  • \b β€” word boundary. Matches between a word character and a non-word character.

Quantifiers

  • ? β€” 0 or 1.
  • * β€” 0 or more.
  • + β€” 1 or more.
  • {n}, {n,}, {n,m} β€” exactly n, at least n, between n and m.

By default, quantifiers are greedy β€” they match as much as possible. Append ? to make them lazy, matching as little as possible. Compare <.*> against <b>bold</b> β€” greedy matches the whole string; <.*?> matches each tag individually.

Groups and alternation

  • (abc) β€” capturing group. Available as $1 in replacements.
  • (?:abc) β€” non-capturing group. Use when you only need grouping for | or quantifiers.
  • (?<name>abc) β€” named capture.
  • a|b β€” alternation (match either side).

Flags

  • g β€” global. Find all matches, not just the first.
  • i β€” case-insensitive.
  • m β€” multiline. ^ and $ match at line boundaries.
  • s β€” dotAll. . matches newlines.

Catastrophic backtracking β€” the bug that brings down services

Nested quantifiers with overlapping alternatives can make a regex take exponential time on an input that's just slightly malformed. A regex that runs in microseconds on valid input can freeze for minutes on a 50-character attack string.

The classic example is ^(a+)+$ against aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!. The engine tries every way to partition the as among the groups before failing. The Cloudflare 2019 outage and multiple ReDoS CVEs trace back to this pattern.

Two defenses:

  • Avoid nested quantifiers that can match the same thing in multiple ways. Rewrite (a+)+ as a+.
  • Set a timeout on any regex run against untrusted input, or use an engine with linear-time guarantees (RE2, Rust's regex crate).

Don't use regex for these

  • Parsing HTML. HTML is not regular. Even a modest real-world page will defeat any regex. Use a proper parser (DOMParser in browsers, cheerio in Node).
  • Parsing JSON, XML, or any nested structure. Same reason.
  • Validating email addresses comprehensively. The full RFC 5321/5322 grammar is enormous. For signup forms, ^\S+@\S+\.\S+$ plus a confirmation email is better than a 500-character regex.
  • Replacing logic you could express as a plain string operation. str.split(',') is clearer than a regex.

FAQ

What's the difference between .* and .*??

.* is greedy β€” it matches as much as possible, then backtracks if the rest of the pattern doesn't fit. .*? is lazy β€” it matches as little as possible, then extends if needed.

Why doesn't \d match non-ASCII digits?

By default in JavaScript it matches only [0-9]. Use the u Unicode flag plus \p{Nd} to match decimal digits in any script. Similar rule for \w.

What does a lookahead actually do?

(?=foo) asserts that foo appears next, without consuming it. (?!foo) asserts it doesn't. Useful when you want to match something followed by a pattern, but keep that pattern out of your match. Example: \d+(?= dollars) captures only the number in "500 dollars".

Why does my pattern behave differently on a different platform?

Regex dialects vary. PCRE (PHP), Python's re, Go's regexp (RE2), Perl, and JavaScript each have small differences β€” flag syntax, Unicode handling, recursion support, named group syntax. If portability matters, stick to the intersection.

Utilities

Common developer utilities that run entirely in your browser.

UID

UUID Generator

Generate random version 4 UUIDs using the browser's built-in cryptographic random number generator.

Output

UUIDs: what they are and which version to use

A UUID (Universally Unique Identifier) is a 128-bit value rendered as a 36-character string like 550e8400-e29b-41d4-a716-446655440000. The point is that you can generate one on any machine, at any time, without coordination, and be practically certain it won't collide with a UUID generated anywhere else.

Multiple versions exist β€” each solves a different problem:

  • v4 (random) β€” 122 bits of randomness. What this tool generates. Good default for anything that doesn't need sortability.
  • v7 (time-ordered) β€” timestamp in the high bits, random in the low bits. Finalized in RFC 9562 (2024). Better for database primary keys: lexicographic sort matches insert order, so B-tree indexes don't fragment.
  • v1 β€” timestamp plus MAC address. Leaks which machine generated it and is largely superseded by v7.
  • v3 / v5 β€” deterministic, hashed from a namespace and name. Useful when the same input should always produce the same UUID (e.g. derive a user's avatar ID from their email).
Rule of thumb: v4 for identifiers that don't hit a database index; v7 for database primary keys in new systems; v5 when you need determinism.

Unix timestamps without the confusion

A Unix timestamp is the number of seconds elapsed since 1970-01-01T00:00:00Z. That instant is called the Unix epoch. The value is the same everywhere on Earth at the same moment β€” it has no time zone.

Seconds vs. milliseconds

Most Unix tooling uses seconds (1718000000). JavaScript's Date.now() returns milliseconds (1718000000000) β€” three extra digits. This is the single most common timestamp bug: a value gets interpreted in the wrong unit and you end up in the year 56,000 or in 1970. A 10-digit number is seconds; a 13-digit number is milliseconds.

Year 2038 (Y2K38)

32-bit signed integers holding seconds overflow on 2038-01-19T03:14:07Z. If your stack still uses 32-bit time_t (some embedded systems, legacy filesystems), timestamps past that point wrap to negative numbers and get interpreted as 1901. Modern 64-bit systems are fine for the next several hundred billion years.

Time zones and timestamps

A Unix timestamp is zone-agnostic. A displayed date is not. Convert at the edges: store UTC, render in the user's local zone. The ISO 8601 representation with a Z suffix (e.g. 2026-04-18T15:30:00Z) is unambiguous and parseable in every language.

Case conversion β€” which case where?

  • camelCase β€” JavaScript/TypeScript variables and functions; JSON keys in JavaScript-first APIs.
  • PascalCase β€” class names, type names, React components, C# everything.
  • snake_case β€” Python, Ruby, Rust variables and functions; SQL column names; JSON keys in Python-first or Rails APIs.
  • kebab-case β€” URLs, CSS class names and custom properties, HTML attributes, filenames, npm package names.
  • UPPER_SNAKE β€” environment variables, constants in most languages, SQL keywords by convention.
  • Title Case β€” headings and UI labels (not code identifiers).

Consistency within a codebase matters more than the specific choice. Most style guides just say: match your language's convention, match any existing API contract, and don't mix on the same side of a boundary.

FAQ

Is a UUID cryptographically secure?

A v4 UUID generated with a cryptographic RNG (like this tool's β€” we use the browser's crypto.getRandomValues) has 122 bits of entropy, which is plenty for unguessability. But UUIDs are not secrets β€” they're identifiers. Don't use one as a session token or access key.

Can two random UUIDs collide?

In theory yes, in practice no. You'd need to generate about 2.71 quintillion (2.71 Γ— 1018) v4 UUIDs to reach a 50% chance of a single collision. If you're generating identifiers fast enough for that to matter, you have a different problem.

How do I tell whether a timestamp is seconds or milliseconds?

Count digits. A seconds timestamp for any recent date is 10 digits. Milliseconds is 13 digits. Microseconds (some Python/Go APIs) is 16 digits. This tool auto-detects seconds vs. milliseconds.

Why does case conversion mangle my identifiers with numbers or acronyms?

Case conversion is ambiguous around boundaries like URLParser (is it "url parser" or "u r l parser"?) and v2Endpoint. Different libraries make different choices. If the input is important, review the output β€” don't blindly run it through a script.

Text Diff

Compare two blocks of text and see the line-by-line differences. Runs entirely in your browser.

Ξ”

Compare Text

Paste the original text on the left and the modified text on the right. The diff updates when you click Compute.

What a diff actually shows

A diff is a compact description of how one text differs from another. Rather than showing both documents side by side, a diff picks out the lines that were added, removed, or changed β€” so you can focus on what's different instead of re-reading what's the same. It's the same view you get from git diff, from a pull request on GitHub, or from the "Compare" feature in most editors.

DevDecoder's diff is a line-based diff: it splits both inputs on newlines, finds the longest common subsequence of matching lines, and marks the rest as additions or deletions. That's the right granularity for config files, JSON payloads, log output, and source code.

When to use a diff

  • Comparing API responses. Capture one response, change a parameter, capture the other β€” the diff tells you exactly which fields changed.
  • Reviewing config changes. Before and after an environment migration, paste the two config files and see which values moved.
  • Verifying redactions. Produce a version of a document with sensitive data removed, diff against the original, confirm nothing else changed.
  • Spotting unintended changes. Paste a file you edited and its original to confirm your changes are scoped to what you intended.
  • Comparing JWTs or decoded payloads. Format both tokens' payloads, diff them, see which claim differs.

Common pitfalls

  • Line-ending drift. Files with \r\n (Windows) and files with \n (Unix) will diff as "every line changed" even when the content is identical. Strip \r before diffing, or use an editor that normalizes on paste.
  • Trailing whitespace. A space at the end of a line makes two otherwise-identical lines look different. Turn on the "ignore whitespace" toggle above, or clean the inputs first.
  • Minification. Minified JSON or minified JS is useless to diff directly β€” everything is one line. Pretty-print both sides first (the JSON formatter handles JSON; run JS through a formatter).
  • Ordering in JSON. Most JSON libraries don't preserve key order. If you diff two JSON documents with the same data but different key order, every line will look changed. Canonicalize first (sort keys consistently) before diffing.
  • Huge inputs. Classical line diff is O(mΒ·n) in memory. Thousand-line inputs diff instantly; 100,000-line inputs will hang the tab. Split large files into chunks or use a local diff tool for those.

FAQ

Does this tool send my text to a server?

No. The entire diff runs in your browser using plain JavaScript. Neither input is transmitted anywhere. That's especially relevant when you're comparing files that contain secrets or customer data.

Is this a character-level or line-level diff?

Line-level. Changes within a line are shown as a delete + add pair. For prose or small changes where you want character-level detail, a dedicated word-diff tool is a better fit; this tool is optimized for code, config, and structured text.

Does the diff match what git diff would show?

The algorithm is similar (both use LCS-style matching), but Git uses a slightly different heuristic for choosing the "best" alignment when multiple valid diffs exist. Expect the set of changed lines to match; the exact grouping of change hunks may differ.

What counts as "changed" if only whitespace differs?

By default, whitespace matters β€” a line with one extra space is a different line. The "Ignore leading/trailing whitespace" toggle trims each line before comparing, which is what you want for most diffs of hand-edited files.

QR Code Generator

Turn any text, URL, or short payload into a QR code. Generated locally in your browser β€” nothing is uploaded.

QR

Generate QR Code

Enter text or a URL, pick a size and error-correction level, and download the result as a PNG.

What a QR code is

A QR (Quick Response) code is a two-dimensional barcode that encodes up to a few thousand characters of text in a square pattern of black and white modules. It was invented at Denso Wave in 1994 for tracking automotive parts and became the dominant way to move short payloads β€” URLs, Wi-Fi credentials, payment links, contact cards β€” between a physical medium and a phone camera.

The content is just text: a QR code does not care whether the text is a URL, a plain string, or a JSON blob. Whatever scanner reads it decides what to do with the result. A URL gets opened. A Wi-Fi string triggers a network join prompt. Anything else is shown as text.

Error correction: L, M, Q, or H?

QR codes include Reed–Solomon error correction so they still scan when part of the code is obscured, printed imperfectly, or faded. The cost is size: a higher correction level means more modules, so the same content produces a denser code.

LevelRecovers fromPick it when
L~7% damageDisplayed on a clean screen; no risk of damage.
M~15% damageGeneral use. A good default for most cases.
Q~25% damageSmall print, glossy surfaces, codes that may be partly covered by a logo.
H~30% damageOutdoor signage, codes printed on textured or curved surfaces, or codes with a brand logo overlaid in the center.

If you plan to place a small logo in the middle of the code, bump to Q or H so the overlay doesn't break scanning.

Capacity, or why your URL might not fit

QR codes come in 40 different "versions," each with progressively more modules. At the highest version and lowest error correction, a code can hold around 4,296 alphanumeric characters or 2,953 bytes β€” plenty for any URL and most short payloads. But bigger versions produce denser codes that are harder to scan at small sizes.

Practical guidance:

  • Keep URLs under ~100 characters where possible. Use a URL shortener if you're over that and scan quality matters.
  • For Wi-Fi connect codes (WIFI:T:WPA;S:<ssid>;P:<password>;;), short SSIDs and passwords scan much more reliably than long ones.
  • vCards fit, but minimize fields. A QR with name, phone, and email scans well; a QR with a full photo embedded does not.

Printing and display tips

  • Quiet zone. Every QR code needs a white border of at least 4 modules around the pattern for scanners to find it. Don't crop it tight.
  • Contrast. Black on white is safest. Colored codes work, but dark-on-light with high contrast is required. Avoid colored backgrounds that match the foreground.
  • Inverted codes do not scan on most mobile scanners. Keep the modules darker than the background.
  • Size for scanning distance. Rule of thumb: the code should be at least 1/10th of the distance the user will scan from. A code to be scanned at 30 cm should be at least 3 cm wide.
  • Avoid glare on curved surfaces. If printing on a bottle or a non-flat medium, test from multiple angles before committing to a print run.

FAQ

Is the QR code generated on the server?

No. Generation happens entirely in your browser using a JavaScript library (qrcodejs). The content you paste is never sent anywhere. That's the same privacy guarantee as every other tool here.

Can I encode binary data?

QR codes support a "byte" mode that can encode arbitrary bytes, but in practice most scanners only handle text cleanly. For binary payloads, Base64-encode first (see the encoder) and paste the result here.

Why do QR codes have three big squares in the corners?

Those are "finder patterns." A scanner uses them to locate the code in the image, figure out its orientation, and determine the size of each module. Without them the scanner doesn't know where the code starts.

My code scans on some phones but not others. Why?

Usually one of: (1) error correction level is too low and the code is partially damaged, (2) contrast between foreground and background is insufficient, (3) the quiet zone around the code is too small, (4) the code is too dense for the scanning distance. Bump the error-correction level and try again.

DevDecoder β€” free developer tools that run in your browser

A small collection of encoding, hashing, and inspection tools for everyday work on APIs, tokens, and text. Everything runs client-side in plain JavaScript β€” your input never leaves your machine.

Why another developer-tools site?

Most online decoders and formatters paste your input straight into a form, post it to a server, and show you the result. That's fine for a lorem ipsum generator β€” it's a real problem when the input is a production JWT, a customer's API response, or a hash of something sensitive. DevDecoder exists because a tool that touches tokens, keys, and payloads has no business sending them off-device.

Every operation you can run here β€” encoding, decoding, hashing, JWT decoding, JSON parsing, regex matching, UUID generation β€” executes in your browser. Open DevTools, open the Network tab, and use any tool: no request is made for the tool logic itself. Hashing uses the browser's SubtleCrypto API. UUIDs come from crypto.getRandomValues. There is no backend. (You will see background requests from Google AdSense, which is disclosed on the Privacy Policy.)

What's here

Encoding & decoding

Six formats covered: Base64 (with the same engine that powers data URIs and HTTP Basic auth), URL percent-encoding, HTML entity escaping, Hex, Binary, and ROT13. Each has its own tab on the Decode page, with explanations of when to use which.

Cryptographic hashes

A single input field produces MD5, SHA-1, SHA-256, SHA-384, and SHA-512 at once. Useful for checksums, HMAC setup, and matching a published file signature. Read the warnings on the Hash page before using any of these for password storage.

JWT decoding

Paste a JSON Web Token to see its decoded header and payload, plus an expiration badge showing whether the token is valid right now. Signature verification requires the key, which we never ask for β€” see the JWT page for how to verify server-side.

JSON, regex, and everyday utilities

A forgiving JSON formatter, a live regex tester with flag toggles and capture-group display, and a small utilities panel covering the three things you actually reach for between other tasks: a UUID, a timestamp conversion, and a case conversion.

Text diff

A line-based diff for comparing two text blocks β€” JSON payloads, config files, code snippets. Shows additions and deletions in a familiar +/- format with per-change line counts.

QR code generator

Turn any URL or short payload into a scannable QR code, with selectable size and error-correction level, and a one-click PNG download. Everything runs in-browser.

Reading guides

Longer-form pieces that go deeper than the inline explanations on each tool page:

The privacy story, briefly

No backend. No analytics requests on tool usage. No input data leaves the browser. The only data we touch is a single theme value in localStorage so your dark-mode choice persists. Google AdSense is loaded for ads, which brings its own cookies β€” those are disclosed on the Privacy Policy.

Questions, bug reports, or feature requests are welcome β€” see the Contact page.