base64url encode/decode
URL friendly data encoding is important when working with data URIs and APIs that work with binary formatted data. base64url is a modification of the base64 encoding that replaces the problematic characters of base64 for URLs. This means swapping ‘+’ for ‘-‘ and ‘/’ for ‘_’, as well as removing the trailing ‘===’ padding.
I found myself needing a concise and dependency free base64url encode/decoder that leverages the native base64 encoding functions. The following is a mix of my own design and elements from numerous alternative solutions from across the internet. There are a number of libraries published to NPM that accomplish this but sometimes adding a dependency adds complexity and risk.
function base64url_encode(buffer: ArrayBuffer): string {
return btoa(Array.from(new Uint8Array(buffer), b => String.fromCharCode(b)).join(''))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
function base64url_decode(value: string): ArrayBuffer {
const m = value.length % 4;
return Uint8Array.from(atob(
value.replace(/-/g, '+')
.replace(/_/g, '/')
.padEnd(value.length + (m === 0 ? 0 : 4 - m), '=')
), c => c.charCodeAt(0)).buffer
}
Things to note about this implementation are:
base64url_decode()
will return an ArrayBuffer that is read only. Usebuffer.slice(0)
to make a writable copy.- The replaceAll and padEnd functions used may require polyfills if you intend to target Internet Explorer.