btoa.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. let i;
  8. // String conversion as required by Web IDL.
  9. s = `${s}`;
  10. // "The btoa() method must throw an "InvalidCharacterError" DOMException if
  11. // data contains any character whose code point is greater than U+00FF."
  12. for (i = 0; i < s.length; i++) {
  13. if (s.charCodeAt(i) > 255) {
  14. return null;
  15. }
  16. }
  17. let out = "";
  18. for (i = 0; i < s.length; i += 3) {
  19. const groupsOfSix = [undefined, undefined, undefined, undefined];
  20. groupsOfSix[0] = s.charCodeAt(i) >> 2;
  21. groupsOfSix[1] = (s.charCodeAt(i) & 0x03) << 4;
  22. if (s.length > i + 1) {
  23. groupsOfSix[1] |= s.charCodeAt(i + 1) >> 4;
  24. groupsOfSix[2] = (s.charCodeAt(i + 1) & 0x0f) << 2;
  25. }
  26. if (s.length > i + 2) {
  27. groupsOfSix[2] |= s.charCodeAt(i + 2) >> 6;
  28. groupsOfSix[3] = s.charCodeAt(i + 2) & 0x3f;
  29. }
  30. for (let j = 0; j < groupsOfSix.length; j++) {
  31. if (typeof groupsOfSix[j] === "undefined") {
  32. out += "=";
  33. } else {
  34. out += btoaLookup(groupsOfSix[j]);
  35. }
  36. }
  37. }
  38. return out;
  39. }
  40. /**
  41. * Lookup table for btoa(), which converts a six-bit number into the
  42. * corresponding ASCII character.
  43. */
  44. function btoaLookup(idx) {
  45. if (idx < 26) {
  46. return String.fromCharCode(idx + "A".charCodeAt(0));
  47. }
  48. if (idx < 52) {
  49. return String.fromCharCode(idx - 26 + "a".charCodeAt(0));
  50. }
  51. if (idx < 62) {
  52. return String.fromCharCode(idx - 52 + "0".charCodeAt(0));
  53. }
  54. if (idx === 62) {
  55. return "+";
  56. }
  57. if (idx === 63) {
  58. return "/";
  59. }
  60. // Throw INVALID_CHARACTER_ERR exception here -- won't be hit in the tests.
  61. return undefined;
  62. }
  63. module.exports = btoa;