const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' function toUtf8Bytes(text) { let out = '' const normalized = String(text).replace(/\r\n/g, '\n') for (let i = 0; i < normalized.length; i++) { const code = normalized.charCodeAt(i) if (code < 128) { out += String.fromCharCode(code) } else if (code < 2048) { out += String.fromCharCode((code >> 6) | 192, (code & 63) | 128) } else { out += String.fromCharCode((code >> 12) | 224, ((code >> 6) & 63) | 128, (code & 63) | 128) } } return out } export default class Base64Codec { encode(plain) { const bytes = toUtf8Bytes(plain) let output = '' for (let i = 0; i < bytes.length;) { const c1 = bytes.charCodeAt(i++) const c2 = bytes.charCodeAt(i++) const c3 = bytes.charCodeAt(i++) const b1 = c1 >> 2 const b2 = ((c1 & 3) << 4) | (isNaN(c2) ? 0 : c2 >> 4) const b3 = isNaN(c2) ? 64 : (((c2 & 15) << 2) | (isNaN(c3) ? 0 : c3 >> 6)) const b4 = isNaN(c3) ? 64 : (c3 & 63) output += ALPHABET[b1] + ALPHABET[b2] + ALPHABET[b3] + ALPHABET[b4] } return output } }