btoa.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. "use strict";
  2. /**
  3. * btoa() as defined by the HTML and Infra specs, which mostly just references
  4. * RFC 4648.
  5. */
  6. function btoa(s) {
  7. if (arguments.length === 0) {
  8. throw new TypeError("1 argument required, but only 0 present.");
  9. }
  10. let i;
  11. // String conversion as required by Web IDL.
  12. s = `${s}`;
  13. // "The btoa() method must throw an "InvalidCharacterError" DOMException if
  14. // data contains any character whose code point is greater than U+00FF."
  15. for (i = 0; i < s.length; i++) {
  16. if (s.charCodeAt(i) > 255) {
  17. return null;
  18. }
  19. }
  20. let out = "";
  21. for (i = 0; i < s.length; i += 3) {
  22. const groupsOfSix = [undefined, undefined, undefined, undefined];
  23. groupsOfSix[0] = s.charCodeAt(i) >> 2;
  24. groupsOfSix[1] = (s.charCodeAt(i) & 0x03) << 4;
  25. if (s.length > i + 1) {
  26. groupsOfSix[1] |= s.charCodeAt(i + 1) >> 4;
  27. groupsOfSix[2] = (s.charCodeAt(i + 1) & 0x0f) << 2;
  28. }
  29. if (s.length > i + 2) {
  30. groupsOfSix[2] |= s.charCodeAt(i + 2) >> 6;
  31. groupsOfSix[3] = s.charCodeAt(i + 2) & 0x3f;
  32. }
  33. for (let j = 0; j < groupsOfSix.length; j++) {
  34. if (typeof groupsOfSix[j] === "undefined") {
  35. out += "=";
  36. } else {
  37. out += btoaLookup(groupsOfSix[j]);
  38. }
  39. }
  40. }
  41. return out;
  42. }
  43. /**
  44. * Lookup table for btoa(), which converts a six-bit number into the
  45. * corresponding ASCII character.
  46. */
  47. const keystr =
  48. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  49. function btoaLookup(index) {
  50. if (index >= 0 && index < 64) {
  51. return keystr[index];
  52. }
  53. // Throw INVALID_CHARACTER_ERR exception here -- won't be hit in the tests.
  54. return undefined;
  55. }
  56. module.exports = btoa;