Base64URL Encoder and Decoder

Convert text, hex bytes or files to URL-safe Base64 and back. The alphabet uses - and _ instead of + and /, and padding is off by default, as in JSON Web Tokens and OAuth PKCE.

Runs entirely in your browser. Nothing is uploaded.

How to use

  1. Choose Encode or Decode. The URL-safe variant is preselected with padding switched off.
  2. Type or paste text, enter hex bytes, or open a file. The result updates as you type.
  3. Turn padding on only if the receiving system requires = signs at the end.
  4. Copy the result or download it.

What is Base64URL?

Base64URL is defined in section 5 of RFC 4648 as "Base 64 Encoding with URL and Filename Safe Alphabet". It works exactly like standard Base64, 6 bits per character, but swaps the two characters that cause trouble in URLs and file paths:

Standard Base64Base64URL
Value 62+-
Value 63/_
Padding=, requiredusually omitted

In a URL, + can be read as a space, / separates path segments and = separates query keys from values, so standard Base64 has to be percent-encoded before it goes into a link. Base64URL needs no escaping. RFC 4648 allows the padding to be dropped when the length is known from context, and most specifications built on Base64URL do exactly that.

Where Base64URL is used

  • JSON Web Tokens. The header, payload and signature of a JWT are each Base64URL without padding (RFC 7515). Read one with the JWT Decoder.
  • OAuth 2.0 PKCE. The code_challenge is the unpadded Base64URL form of the SHA-256 hash of the code verifier (RFC 7636), so it is always 43 characters long.
  • JSON Web Keys and WebAuthn. Key parameters such as n, e, x and y, as well as WebAuthn challenges and credential IDs, are exchanged as Base64URL.
  • Tokens, IDs and file names. Reset links, signed URLs and cache keys carry Base64URL without escaping; a 16-byte random ID becomes 22 characters. On case-insensitive file systems, prefer Base32, because Base64URL depends on letter case.

Converting between Base64 and Base64URL

Both variants encode the same bytes, so converting is a character swap: replace + with - and / with _, then remove trailing =. To go back, swap the characters again and add = until the length is a multiple of 4. The decoder on this page accepts both alphabets, with or without padding.

// Node.js 16+
Buffer.from(data).toString('base64url')
Buffer.from(str, 'base64url')

# Python (urlsafe_b64encode keeps the padding)
base64.urlsafe_b64encode(data).rstrip(b'=')

// Go
base64.RawURLEncoding.EncodeToString(data)

// Java
Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)

Specification

AlphabetA-Z a-z 0-9 - _
Output size4 characters per 3 bytes (about 133%)
PaddingOptional, usually omitted
StandardRFC 4648 section 5
Case sensitiveYes

Examples

Input (UTF-8)Output
Hello, World!SGVsbG8sIFdvcmxkIQ
Base64.isQmFzZTY0Lmlz
你好5L2g5aW9

Frequently asked questions

Is Base64URL the same as URL-encoding a Base64 string?
No. Percent-encoding standard Base64 turns +, / and = into %2B, %2F and %3D, which makes the string longer. Base64URL uses a different alphabet, so no escaping is needed at all. The two forms are not interchangeable without converting.
Should Base64URL have padding?
It depends on the consumer. JWT, JSON Web Keys and PKCE require the padding to be left out, while Python's urlsafe_b64encode and Java's default URL encoder add it. When in doubt, omit it; this decoder accepts both forms.
Why does a standard Base64 decoder reject my Base64URL string?
Strict standard decoders do not accept - and _, and some require padding. Swap the characters and add = signs to make the length a multiple of 4, or decode the string here.
How do I check a PKCE code challenge?
The challenge is BASE64URL(SHA256(code_verifier)) without padding. Decode it here with hex output: a correct value gives exactly 32 bytes, which you can compare with the SHA-256 hash of the verifier.