Last active
March 11, 2021 03:27
-
-
Save paulownia/86a1692e873d335dbb89e8bc55c2e74a to your computer and use it in GitHub Desktop.
base64 encode/decode with Uint8Array on browser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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