67 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| /**
 | |
|  * btoa() as defined by the HTML and Infra specs, which mostly just references
 | |
|  * RFC 4648.
 | |
|  */
 | |
| function btoa(s) {
 | |
|   let i;
 | |
|   // String conversion as required by Web IDL.
 | |
|   s = `${s}`;
 | |
|   // "The btoa() method must throw an "InvalidCharacterError" DOMException if
 | |
|   // data contains any character whose code point is greater than U+00FF."
 | |
|   for (i = 0; i < s.length; i++) {
 | |
|     if (s.charCodeAt(i) > 255) {
 | |
|       return null;
 | |
|     }
 | |
|   }
 | |
|   let out = "";
 | |
|   for (i = 0; i < s.length; i += 3) {
 | |
|     const groupsOfSix = [undefined, undefined, undefined, undefined];
 | |
|     groupsOfSix[0] = s.charCodeAt(i) >> 2;
 | |
|     groupsOfSix[1] = (s.charCodeAt(i) & 0x03) << 4;
 | |
|     if (s.length > i + 1) {
 | |
|       groupsOfSix[1] |= s.charCodeAt(i + 1) >> 4;
 | |
|       groupsOfSix[2] = (s.charCodeAt(i + 1) & 0x0f) << 2;
 | |
|     }
 | |
|     if (s.length > i + 2) {
 | |
|       groupsOfSix[2] |= s.charCodeAt(i + 2) >> 6;
 | |
|       groupsOfSix[3] = s.charCodeAt(i + 2) & 0x3f;
 | |
|     }
 | |
|     for (let j = 0; j < groupsOfSix.length; j++) {
 | |
|       if (typeof groupsOfSix[j] === "undefined") {
 | |
|         out += "=";
 | |
|       } else {
 | |
|         out += btoaLookup(groupsOfSix[j]);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return out;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Lookup table for btoa(), which converts a six-bit number into the
 | |
|  * corresponding ASCII character.
 | |
|  */
 | |
| function btoaLookup(idx) {
 | |
|   if (idx < 26) {
 | |
|     return String.fromCharCode(idx + "A".charCodeAt(0));
 | |
|   }
 | |
|   if (idx < 52) {
 | |
|     return String.fromCharCode(idx - 26 + "a".charCodeAt(0));
 | |
|   }
 | |
|   if (idx < 62) {
 | |
|     return String.fromCharCode(idx - 52 + "0".charCodeAt(0));
 | |
|   }
 | |
|   if (idx === 62) {
 | |
|     return "+";
 | |
|   }
 | |
|   if (idx === 63) {
 | |
|     return "/";
 | |
|   }
 | |
|   // Throw INVALID_CHARACTER_ERR exception here -- won't be hit in the tests.
 | |
|   return undefined;
 | |
| }
 | |
| 
 | |
| module.exports = btoa;
 |