37 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			37 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import { alphabetByEncoding, bitsPerByte, bitsPerLetter } from "./constants.browser";
 | 
						|
export const fromBase64 = (input) => {
 | 
						|
    let totalByteLength = (input.length / 4) * 3;
 | 
						|
    if (input.slice(-2) === "==") {
 | 
						|
        totalByteLength -= 2;
 | 
						|
    }
 | 
						|
    else if (input.slice(-1) === "=") {
 | 
						|
        totalByteLength--;
 | 
						|
    }
 | 
						|
    const out = new ArrayBuffer(totalByteLength);
 | 
						|
    const dataView = new DataView(out);
 | 
						|
    for (let i = 0; i < input.length; i += 4) {
 | 
						|
        let bits = 0;
 | 
						|
        let bitLength = 0;
 | 
						|
        for (let j = i, limit = i + 3; j <= limit; j++) {
 | 
						|
            if (input[j] !== "=") {
 | 
						|
                if (!(input[j] in alphabetByEncoding)) {
 | 
						|
                    throw new TypeError(`Invalid character ${input[j]} in base64 string.`);
 | 
						|
                }
 | 
						|
                bits |= alphabetByEncoding[input[j]] << ((limit - j) * bitsPerLetter);
 | 
						|
                bitLength += bitsPerLetter;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                bits >>= bitsPerLetter;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        const chunkOffset = (i / 4) * 3;
 | 
						|
        bits >>= bitLength % bitsPerByte;
 | 
						|
        const byteLength = Math.floor(bitLength / bitsPerByte);
 | 
						|
        for (let k = 0; k < byteLength; k++) {
 | 
						|
            const offset = (byteLength - k - 1) * bitsPerByte;
 | 
						|
            dataView.setUint8(chunkOffset + k, (bits & (255 << offset)) >> offset);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return new Uint8Array(out);
 | 
						|
};
 |