Base64 URL-safe
Encode and decode URL-safe Base64 (Base64url)
Plain Text
Base64
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.
Base64url Use Cases
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:
| Feature | Standard (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:
| Input | Standard Base64 | Base64url (no padding) |
|---|---|---|
| Hello | SGVsbG8= | SGVsbG8 |
| A | QQ== | |
| 1+1=2 | MSsxPTI= | MSsxPTI |
| subject?ref=1 | c3ViamVjdD9yZWY9MQ== | 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:
// 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!"// 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" }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!'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!"
}