Loading pageā¦
Rust walkthroughs
Loading pageā¦
base64::engine::general_purpose::STANDARD and URL_SAFE encoding configurations?The base64 crate's STANDARD and URL_SAFE configurations encode the same binary data into different character sets, choosing between compatibility with standard Base64 (RFC 4648) and URL-safe encoding. STANDARD uses + and / as the 62nd and 63rd characters, which require escaping in URLs, while URL_SAFE replaces these with - and _ respectively. This choice affects where encoded strings can be used directly, whether they need escaping, and how they interact with other systems expecting specific Base64 variants. Understanding these trade-offs is essential for encoding data that will transit through URLs, filenames, or other contexts with restricted character sets.
use base64::{Engine as _, engine::general_purpose::STANDARD};
fn standard_encoding() {
let data = b"Hello, World!";
let encoded = STANDARD.encode(data);
println!("Standard: {}", encoded);
// Uses + and / for characters 62 and 63
// Example: binary [251, 255] encodes to "/+8="
let decoded = STANDARD.decode(&encoded).unwrap();
assert_eq!(data, decoded.as_slice());
}STANDARD follows RFC 4648 standard Base64, using + and / for the final two characters.
use base64::{Engine as _, engine::general_purpose::URL_SAFE};
fn urlsafe_encoding() {
let data = b"Hello, World!";
let encoded = URL_SAFE.encode(data);
println!("URL-safe: {}", encoded);
// Uses - and _ for characters 62 and 63
// These characters don't need escaping in URLs
let decoded = URL_SAFE.decode(&encoded).unwrap();
assert_eq!(data, decoded.as_slice());
}URL_SAFE uses - and _ which are safe in URLs without escaping.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn character_set_comparison() {
// Both use A-Z, a-z, 0-9 for first 62 characters
// Binary data that uses the special characters
let uses_plus = vec![251u8]; // Encodes with +
let uses_slash = vec![255u8]; // Encodes with /
let std_plus = STANDARD.encode(&uses_plus);
let std_slash = STANDARD.encode(&uses_slash);
let url_plus = URL_SAFE.encode(&uses_plus);
let url_slash = URL_SAFE.encode(&uses_slash);
println!("STANDARD: {} and {}", std_plus, std_slash); // Contains + and /
println!("URL_SAFE: {} and {}", url_plus, url_slash); // Contains - and _
// The + character becomes - in URL_SAFE
// The / character becomes _ in URL_SAFE
}The character substitutions make URL-safe encoding safe for URL paths and query parameters.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn url_example() {
let data = b"some data with / special + characters";
// STANDARD encoding produces characters that need escaping
let standard = STANDARD.encode(data);
let url_with_standard = format!("https://example.com/data?value={}", standard);
// The + and / would need URL encoding
// URL_SAFE encoding produces URL-safe output
let urlsafe = URL_SAFE.encode(data);
let url_with_urlsafe = format!("https://example.com/data?value={}", urlsafe);
// No additional escaping needed
println!("Standard needs escaping: {}", url_with_standard);
println!("URL-safe is ready: {}", url_with_urlsafe);
}URL_SAFE output can be used directly in URLs without additional encoding.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE, URL_SAFE_NO_PAD}};
fn padding_comparison() {
let data = b"Hello";
// STANDARD and URL_SAFE both use padding by default
let with_pad = URL_SAFE.encode(data);
println!("With padding: {}", with_pad); // "SGVsbG8="
// URL_SAFE_NO_PAD removes padding
let no_pad = URL_SAFE_NO_PAD.encode(data);
println!("Without padding: {}", no_pad); // "SGVsbG8"
// Padding can cause issues in:
// - Filenames (= is special in some filesystems)
// - URLs (= is used for query parameters)
// - JSON Web Tokens (JWT uses unpadded Base64)
}Padding with = characters can cause issues in URLs and other contexts.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn decoding_compatibility() {
// Cannot mix STANDARD and URL_SAFE for encoding/decoding
let standard_encoded = "SGVsbG8+Pz8="; // Contains +
let urlsafe_encoded = "SGVsbG8-_w=="; // Contains - and _
// Must use matching decoder
// STANDARD.decode(&urlsafe_encoded) would fail on - or _
// URL_SAFE.decode(&standard_encoded) would fail on + or /
let decoded_standard = STANDARD.decode(standard_encoded).unwrap();
let decoded_urlsafe = URL_SAFE.decode(urlsafe_encoded).unwrap();
// Same original data produces different encodings
}Decoding requires matching the encoding configuration.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn filename_example() {
let identifier = b"unique/id+value";
// STANDARD encoding contains / which is path separator
let standard_name = STANDARD.encode(identifier);
// Would create: "dW5pcXVlL2lkK3ZhbHVl" - contains /
// URL_SAFE encoding avoids / and +
let safe_name = URL_SAFE.encode(identifier);
// Creates: "dW5pcXVlL2lkK3ZhbHVl" - but with _ instead of /
// Actually URL_SAFE would give: "dW5pcXVl_lidK3ZhbHVl"
// Safe for filenames on most filesystems
// Use in filename
let filename = format!("cache/{}.bin", safe_name);
println!("Safe filename: {}", filename);
}URL_SAFE avoids characters that are problematic in filenames.
| Configuration | Character 62 | Character 63 | Padding | Use Case |
|--------------|--------------|--------------|---------|----------|
| STANDARD | + | / | Yes | Standard Base64 |
| STANDARD_NO_PAD | + | / | No | Standard without padding |
| URL_SAFE | - | _ | Yes | URLs, filenames |
| URL_SAFE_NO_PAD | - | _ | No | JWTs, URLs without = |
use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
fn jwt_example() {
// JWTs use URL-safe Base64 without padding
let header = br#"{"alg":"HS256","typ":"JWT"}"#;
let payload = br#"{"sub":"1234567890","name":"John Doe"}"#;
let header_b64 = URL_SAFE_NO_PAD.encode(header);
let payload_b64 = URL_SAFE_NO_PAD.encode(payload);
println!("Header: {}", header_b64);
println!("Payload: {}", payload_b64);
// JWT format: header.payload.signature
let jwt = format!("{}.{}.signature", header_b64, payload_b64);
println!("JWT: {}", jwt);
// No padding means no = characters to escape
}JWTs require unpadded URL-safe Base64 for compact token format.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn database_example() {
let binary_data = vec![0u8, 255, 127, 63, 191];
// STANDARD is conventional for storage
let stored_standard = STANDARD.encode(&binary_data);
// URL_SAFE works too, but ensure consistency
let stored_urlsafe = URL_SAFE.encode(&binary_data);
// Important: Use the same encoding for storage and retrieval
// Don't mix encodings in the same database column
// STANDARD is more widely recognized
// URL_SAFE may require documentation for consumers
}Choose one encoding consistently for database storage.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn interoperability() {
// Many systems expect STANDARD encoding
// - PEM certificates
// - MIME messages
// - HTTP Basic Auth
// HTTP Basic Auth
let credentials = "user:password";
let auth_header = format!("Basic {}", STANDARD.encode(credentials));
// URL_SAFE is expected by:
// - JWT libraries
// - URL-safe APIs
// - Some cloud storage keys
// Match the encoding expected by the target system
// When receiving encoded data, may need to detect format:
let encoded = "SGVsbG8+World";
let uses_standard_chars = encoded.contains('+') || encoded.contains('/');
let uses_urlsafe_chars = encoded.contains('-') || encoded.contains('_');
}Match the encoding expected by external systems.
use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
fn query_parameter_example() {
let session_data = br#"{"user_id": 123, "exp": 1234567890}"#;
let encoded = URL_SAFE_NO_PAD.encode(session_data);
// Safe to include directly in URL
let url = format!("https://example.com/session?data={}", encoded);
// With STANDARD encoding, would need:
// let standard_encoded = STANDARD.encode(session_data);
// let escaped = urlencoding::encode(&standard_encoded);
// let url = format!("https://example.com/session?data={}", escaped);
println!("URL: {}", url);
}URL_SAFE_NO_PAD eliminates need for additional URL encoding.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn performance_comparison() {
// Both configurations have identical performance
// The only difference is the character lookup table
let data = vec![0u8; 10_000];
let start = std::time::Instant::now();
let _standard = STANDARD.encode(&data);
let standard_time = start.elapsed();
let start = std::time::Instant::now();
let _urlsafe = URL_SAFE.encode(&data);
let urlsafe_time = start.elapsed();
// Times should be nearly identical
println!("Standard: {:?}", standard_time);
println!("URL-safe: {:?}", urlsafe_time);
}Encoding and decoding performance is identical between variants.
use base64::{Engine as _, engine::general_purpose::{GeneralPurpose, PAD}, alphabet::{URL_SAFE, STANDARD}};
fn custom_configuration() {
// Custom configuration is possible but rarely needed
// The provided STANDARD and URL_SAFE cover most cases
// If you need a custom alphabet:
let custom = GeneralPurpose::new(&URL_SAFE, PAD);
// Or unpadded:
let custom_no_pad = GeneralPurpose::new(&STANDARD, base64::engine::general_purpose::NO_PAD);
}Custom configurations are available for specialized needs.
use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct ApiResponse {
id: String,
binary_data: String,
}
fn api_example() {
// API needs to return binary data as string
let binary_content = vec![0xDE, 0xAD, 0xBE, 0xEF];
// Use URL_SAFE for API responses that might be used in URLs
let encoded = URL_SAFE_NO_PAD.encode(&binary_content);
let response = ApiResponse {
id: "123".to_string(),
binary_data: encoded,
};
let json = serde_json::to_string(&response).unwrap();
println!("API response: {}", json);
// Client can safely use this in subsequent API calls
}APIs returning binary data often use URL-safe encoding for flexibility.
use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
fn generate_token(identifier: &str, secret: &str) -> String {
// Create a unique token with timestamp
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
let token_data = format!("{}:{}", identifier, timestamp);
let encoded = URL_SAFE_NO_PAD.encode(token_data.as_bytes());
// Add a signature component
let signature = format!("{}:{}", encoded, "signature");
URL_SAFE_NO_PAD.encode(signature.as_bytes())
}
fn token_in_url() {
let token = generate_token("user123", "secret");
// Token is safe for URLs
let url = format!("https://example.com/verify?token={}", token);
println!("Verification URL: {}", url);
}Tokens embedded in URLs benefit from URL-safe encoding.
use base64::{Engine as _, engine::general_purpose::{STANDARD, URL_SAFE}};
fn convert_encoding() {
// To convert from STANDARD to URL_SAFE:
let standard_encoded = "SGVsbG8+World/==";
// 1. Decode with STANDARD
let decoded = STANDARD.decode(standard_encoded).unwrap();
// 2. Re-encode with URL_SAFE
let urlsafe_encoded = URL_SAFE.encode(&decoded);
println!("Converted: {}", urlsafe_encoded);
// Direct string substitution is also possible:
// + becomes -
// / becomes _
// But re-encoding is safer and handles padding correctly
}Converting between encodings requires decode-then-encode cycle.
Key differences:
| Aspect | STANDARD | URL_SAFE |
|--------|----------|----------|
| Character 62 | + | - |
| Character 63 | / | _ |
| URL-safe | No (needs escaping) | Yes |
| Filename-safe | No (/ is separator) | Generally yes |
| RFC reference | RFC 4648 §4 | RFC 4648 §5 |
| Common use | PEM, MIME, Basic Auth | JWTs, URLs, tokens |
When to use each:
| Use Case | Recommended Encoding | |----------|---------------------| | HTTP headers | STANDARD | | PEM certificates | STANDARD | | Database storage | STANDARD (conventional) | | URL query params | URL_SAFE_NO_PAD | | JWTs | URL_SAFE_NO_PAD | | Filenames | URL_SAFE | | API responses | URL_SAFE (flexible) | | Cross-system interchange | STANDARD (widely supported) |
Key insight: The STANDARD and URL_SAFE configurations encode identical binary data using different character setsāSTANDARD uses + and / which require escaping in URLs, while URL_SAFE substitutes - and _ which are safe unescaped. The encoding choice affects where the output can be used directly: URL_SAFE output works in URLs, filenames, and query parameters without additional escaping, while STANDARD is the conventional choice for PEM certificates, MIME, HTTP Basic Auth, and storage. Padding (= characters) adds another dimension: URL_SAFE_NO_PAD is ideal for JWTs and URLs where padding causes parsing issues. The performance is identical between variantsāthe choice is purely about interoperability and context safety. When choosing, consider whether the encoded string will pass through URL routing, filesystems, or other contexts with restricted characters, and whether downstream systems expect a specific encoding variant.