Skip to content

Instantly share code, notes, and snippets.

@paulownia
Last active March 11, 2021 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulownia/86a1692e873d335dbb89e8bc55c2e74a to your computer and use it in GitHub Desktop.
Save paulownia/86a1692e873d335dbb89e8bc55c2e74a to your computer and use it in GitHub Desktop.
base64 encode/decode with Uint8Array on browser
const table = [];
for (let i = 65; i < 91; i++) table.push(String.fromCharCode(i));
for (let i = 97; i < 123; i++) table.push(String.fromCharCode(i));
for (let i = 0; i < 10; i++) table.push(i.toString(10));
table.push("+");
table.push("/");
const rev_table = table.reduce((obj, c, i) => {
obj[c] = i;
return obj;
}, {});
function encode(bytes) {
if (bytes instanceof Array) {
bytes = Uint8Array.from(bytes);
} else if(!(bytes instanceof Uint8Array || bytes instanceof Uint8ClampedArray)) {
bytes = new TextEncoder().encode(bytes.toString());
}
let base64 = "";
const len = bytes.byteLength;
for (let i = 0; i < len; i += 3) {
if (len === i + 1) { // last 1 byte
const a = (bytes[i] & 0xfc) >> 2;
const b = ((bytes[i] & 0x03) << 4);
base64 += table[a];
base64 += table[b];
base64 += "==";
} else if (len === i + 2) { // last 2 bytes
const a = (bytes[i] & 0xfc) >> 2;
const b = ((bytes[i] & 0x03) << 4) | ((bytes[i+1] & 0xf0) >> 4);
const c = ((bytes[i+1] & 0x0f) << 2);
base64 += table[a];
base64 += table[b];
base64 += table[c];
base64 += "=";
} else {
const a = (bytes[i] & 0xfc) >> 2;
const b = ((bytes[i] & 0x03) << 4) | ((bytes[i+1] & 0xf0) >> 4);
const c = ((bytes[i+1] & 0x0f) << 2) | ((bytes[i+2] & 0xc0) >> 6);
const d = bytes[i+2] & 0x3f;
base64 += table[a];
base64 += table[b];
base64 += table[c];
base64 += table[d];
}
}
return base64;
}
function decode(base64str) {
const len = base64str.length;
//if (len % 4 !== 0) {
// base64str = base64str.padEnd(len + 4 - (len % 4), "=")
//}
const bytes = [];
for (let i = 0; i < len; i += 4) {
const a = rev_table[base64str[i ]];
const b = rev_table[base64str[i+1]];
const c = rev_table[base64str[i+2]];
const d = rev_table[base64str[i+3]];
bytes.push((a << 2 & 0xfc) | (b >> 4 & 0x03));
bytes.push((b << 4 & 0xf0) | (c >> 2 & 0x0f));
bytes.push((c << 6 & 0xc0) | d & 0x3f);
}
return bytes;
}
function decodeAsArrayBuffer(base64str) {
return Uint8Array.from(decode(base64str));
}
function decodeAsString(base64str) {
return new TextDecoder().decode(decodeAsArrayBuffer(base64str));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment