Base64 URL-safe

Encode and decode URL-safe Base64 (Base64url)

Plain Text

Base64

Runs locally · Safe to paste secrets
Base64 output...

What Is Base64url Encoding?

Base64url is a variant of Base64 encoding designed specifically for use in URLs, filenames, and other contexts where the standard Base64 characters + and / cause problems. Defined in RFC 4648 Section 5, Base64url replaces + with - (hyphen) and / with _ (underscore), and omits the trailing = padding characters. The result is a string that can be embedded directly in a URL query parameter, a filename, or an HTTP header without requiring additional percent-encoding.

Standard Base64 (RFC 4648 Section 4) uses 64 characters: A-Z, a-z, 0-9, +, and /. The + and / characters are reserved in URLs: + is interpreted as a space in query strings (application/x-www-form-urlencoded), and / is a path delimiter. Using standard Base64 inside a URL therefore requires percent-encoding these characters (%2B, %2F), which increases the string length and makes it harder to read. Base64url eliminates this problem entirely by using URL-safe characters from the start.

The most prominent use of Base64url is in JSON Web Tokens (JWT). All three segments of a JWT — header, payload, and signature — are Base64url-encoded. OAuth 2.0 PKCE code verifiers, WebAuthn challenge values, and many API token schemes also rely on Base64url. Understanding this encoding is essential for any developer who works with authentication, authorization, or cryptographic data exchange.

Why Use This Base64url Tool?

Convert between Base64url and text or binary data directly in your browser. Both encoding and decoding are supported, with automatic handling of padding and character substitution.

Instant Conversion
Output updates as you type. Encode text to Base64url or decode Base64url back to text with zero delay — no form submissions or page reloads.
🔗
URL-Safe Output
The output uses only characters that are safe in URLs, filenames, and HTTP headers: A-Z, a-z, 0-9, hyphen, and underscore. No percent-encoding needed.
🔒
Privacy-First Processing
All encoding and decoding runs locally in your browser. JWT tokens, OAuth secrets, and API keys you paste here are never transmitted to any server.
🏛️
Standards-Compliant
Implements RFC 4648 Section 5 exactly: - and _ replace + and /, padding is omitted. Compatible with JWT libraries, OAuth 2.0 PKCE, and WebAuthn implementations.

Base64url Use Cases

JWT Token Inspection
Decode individual JWT segments (header, payload) to inspect claims, expiration times, and signing algorithms without importing a JWT library or verifying the signature.
OAuth 2.0 PKCE Flow
Generate and verify PKCE code_verifier and code_challenge values. The code_challenge_method S256 requires a Base64url-encoded SHA-256 hash of the code_verifier.
WebAuthn / FIDO2 Integration
WebAuthn challenge, credential ID, and attestation data are transmitted as Base64url strings between the browser and relying party server. Decode them to debug registration and authentication flows.
API Token Generation
Create URL-safe tokens from random bytes for password-reset links, email verification, and session identifiers. Base64url produces compact strings that work in URLs without escaping.
DevOps and CI/CD Pipelines
Store binary configuration values (certificates, keys) as Base64url strings in environment variables or YAML files. Unlike standard Base64, the output contains no characters that conflict with shell expansion or YAML syntax.
Data Engineering
Encode binary identifiers, hashes, or checksums as Base64url for use in filenames, database keys, or CSV columns where + and / characters would break parsing or require escaping.

Standard Base64 vs Base64url

Base64url differs from standard Base64 in exactly three ways. The encoding algorithm is identical — only the alphabet and padding behavior change:

FeatureStandard (RFC 4648 §4)Base64url (RFC 4648 §5)
Index 62+-
Index 63/_
Padding= (required)Omitted

These three differences mean that converting between standard Base64 and Base64url is trivial: replace + with -, / with _, and strip trailing = characters. In reverse, replace - with +, _ with /, and re-add padding to make the length a multiple of 4. Most languages provide native Base64url support, making manual conversion unnecessary.

Encoding Comparison Table

The table below shows the same inputs encoded with standard Base64 and Base64url. Notice how padding characters (=) are stripped and + / / are replaced with - / _ in the URL-safe variant:

InputStandard Base64Base64url (no padding)
HelloSGVsbG8=SGVsbG8
AQQ==QQ
1+1=2MSsxPTI=MSsxPTI
subject?ref=1c3ViamVjdD9yZWY9MQ==c3ViamVjdD9yZWY9MQ
👍 (thumbs up)8J+RjQ==8J-RjQ

Code Examples

How to encode and decode Base64url strings in popular languages. Every example produces output that is safe for use in URLs, filenames, and HTTP headers:

JavaScript (browser)
// Encode to Base64url
function toBase64url(str) {
  return btoa(unescape(encodeURIComponent(str)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '')
}
toBase64url('Hello!') // → "SGVsbG8h"

// Decode from Base64url
function fromBase64url(b64url) {
  const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/')
  const pad = (4 - b64.length % 4) % 4
  return decodeURIComponent(escape(atob(b64 + '='.repeat(pad))))
}
fromBase64url('SGVsbG8h') // → "Hello!"
Node.js
// Native base64url support since Node 15.7
const encoded = Buffer.from('Hello!').toString('base64url')
// → "SGVsbG8h"

const decoded = Buffer.from('SGVsbG8h', 'base64url').toString()
// → "Hello!"

// Decode a JWT payload
const jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0...'
const payload = JSON.parse(Buffer.from(jwt.split('.')[1], 'base64url').toString())
// → { sub: "1234567890" }
Python
import base64

# Encode to Base64url (no padding)
encoded = base64.urlsafe_b64encode(b'Hello!').rstrip(b'=').decode()
# → "SGVsbG8h"

# Decode from Base64url (re-add padding)
def b64url_decode(s: str) -> bytes:
    s += '=' * (4 - len(s) % 4)  # restore padding
    return base64.urlsafe_b64decode(s)

b64url_decode('SGVsbG8h')  # → b'Hello!'
Go
package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    // Encode to Base64url (no padding)
    encoded := base64.RawURLEncoding.EncodeToString([]byte("Hello!"))
    fmt.Println(encoded) // → "SGVsbG8h"

    // Decode from Base64url
    decoded, _ := base64.RawURLEncoding.DecodeString("SGVsbG8h")
    fmt.Println(string(decoded)) // → "Hello!"
}

Frequently Asked Questions

What is the difference between Base64 and Base64url?
Base64url replaces + with - and / with _ from the standard Base64 alphabet, and omits trailing = padding characters. This makes the output safe for use in URLs, query parameters, filenames, and HTTP headers without additional encoding. The underlying algorithm (splitting bytes into 6-bit groups mapped to ASCII characters) is identical.
Why do JWT tokens use Base64url instead of standard Base64?
JWTs are frequently transmitted in URL query parameters and HTTP Authorization headers. Standard Base64 characters + and / would need to be percent-encoded in URLs, increasing length and breaking simple string comparisons. The JWT specification (RFC 7519) mandates Base64url with no padding to ensure tokens are compact and URL-safe by default.
How do I convert standard Base64 to Base64url?
Replace every + with -, every / with _, and remove all trailing = characters. In JavaScript: base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''). In Python: base64.urlsafe_b64encode(data).rstrip(b'='). Most modern languages also provide a dedicated Base64url encoding function.
Is Base64url encoding reversible?
Yes, Base64url is fully reversible. To decode, replace - with + and _ with /, add back padding = characters to make the length a multiple of 4, then decode as standard Base64. The decoded output is byte-for-byte identical to the original input.
Can I use Base64url for encrypting data?
No. Base64url is an encoding, not encryption. It transforms binary data into a text-safe format without any secrecy — anyone can decode it. If you need to protect data, encrypt it first with a proper algorithm (AES, ChaCha20), then Base64url-encode the ciphertext for transport.
Why is padding omitted in Base64url?
Padding characters (=) serve no purpose when the decoder can compute the missing byte count from the string length: (4 - length % 4) % 4 gives the padding needed. Omitting padding makes the string shorter and avoids = characters, which would need percent-encoding in URLs. RFC 4648 Section 5 explicitly permits omitting padding in Base64url.
How do I handle Base64url strings with padding in my code?
Some systems produce Base64url strings that retain = padding. Most decoders handle this correctly. If yours does not, strip trailing = before decoding. Conversely, if a library requires padding, compute and append it: const padded = str + '='.repeat((4 - str.length % 4) % 4). This works because the padding count is deterministic from the string length.