const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' ; const base64GroupLength = 4 ; const nonBase64Chars = new RegExp ( `[^${ chars }=]` , 'u' ) ; param maybeHex export const isBase64 = ( maybeBase64 ) => maybeBase64 . length % base64GroupLength === 0 && ! nonBase64Chars . test ( maybeBase64 ) ; param validBase64 export const base64ToBin = ( validBase64 ) => { const lookup = new Uint8Array ( 123 ) ; for ( let i = 0 ; i < chars . length ; i ++ ) { lookup [ chars . charCodeAt ( i ) ] = i ; } const bufferLengthEstimate = validBase64 . length * 0.75 ; const stringLength = validBase64 . length ; const bufferLength = validBase64 [ validBase64 . length - 1 ] === '=' ? validBase64 [ validBase64 . length - 2 ] === '=' ? bufferLengthEstimate - 2 : bufferLengthEstimate - 1 : bufferLengthEstimate ; const buffer = new ArrayBuffer ( bufferLength ) ; const bytes = new Uint8Array ( buffer ) ; let p = 0 ; for ( let i = 0 ; i < stringLength ; i += 4 ) { const encoded1 = lookup [ validBase64 . charCodeAt ( i ) ] ; const encoded2 = lookup [ validBase64 . charCodeAt ( i + 1 ) ] ; const encoded3 = lookup [ validBase64 . charCodeAt ( i + 2 ) ] ; const encoded4 = lookup [ validBase64 . charCodeAt ( i + 3 ) ] ; bytes [ p ++ ] = ( encoded1 << 2 ) | ( encoded2 >> 4 ) ; bytes [ p ++ ] = ( ( encoded2 & 15 ) << 4 ) | ( encoded3 >> 2 ) ; bytes [ p ++ ] = ( ( encoded3 & 3 ) << 6 ) | ( encoded4 & 63 ) ; } return bytes ; } ; param bytes export const binToBase64 = ( bytes ) => { let result = '' ; for ( let i = 0 ; i < bytes . length ; i += 3 ) { result += chars [ bytes [ i ] >> 2 ] ; result += chars [ ( ( bytes [ i ] & 3 ) << 4 ) | ( bytes [ i + 1 ] >> 4 ) ] ; result += chars [ ( ( bytes [ i + 1 ] & 15 ) << 2 ) | ( bytes [ i + 2 ] >> 6 ) ] ; result += chars [ bytes [ i + 2 ] & 63 ] ; } const padded = bytes . length % 3 === 2 ? `${ result . substring ( 0 , result . length - 1 ) }=` : bytes . length % 3 === 1 ? `${ result . substring ( 0 , result . length - 2 ) }==` : result ; return padded ; } ;