enc-base64.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import {
  2. WordArray,
  3. } from './core.js';
  4. const parseLoop = (base64Str, base64StrLength, reverseMap) => {
  5. const words = [];
  6. let nBytes = 0;
  7. for (let i = 0; i < base64StrLength; i += 1) {
  8. if (i % 4) {
  9. const bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
  10. const bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
  11. const bitsCombined = bits1 | bits2;
  12. words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
  13. nBytes += 1;
  14. }
  15. }
  16. return WordArray.create(words, nBytes);
  17. };
  18. /**
  19. * Base64 encoding strategy.
  20. */
  21. export const Base64 = {
  22. /**
  23. * Converts a word array to a Base64 string.
  24. *
  25. * @param {WordArray} wordArray The word array.
  26. *
  27. * @return {string} The Base64 string.
  28. *
  29. * @static
  30. *
  31. * @example
  32. *
  33. * const base64String = CryptoJS.enc.Base64.stringify(wordArray);
  34. */
  35. stringify(wordArray) {
  36. // Shortcuts
  37. const { words, sigBytes } = wordArray;
  38. const map = this._map;
  39. // Clamp excess bits
  40. wordArray.clamp();
  41. // Convert
  42. const base64Chars = [];
  43. for (let i = 0; i < sigBytes; i += 3) {
  44. const byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
  45. const byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
  46. const byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
  47. const triplet = (byte1 << 16) | (byte2 << 8) | byte3;
  48. for (let j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j += 1) {
  49. base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
  50. }
  51. }
  52. // Add padding
  53. const paddingChar = map.charAt(64);
  54. if (paddingChar) {
  55. while (base64Chars.length % 4) {
  56. base64Chars.push(paddingChar);
  57. }
  58. }
  59. return base64Chars.join('');
  60. },
  61. /**
  62. * Converts a Base64 string to a word array.
  63. *
  64. * @param {string} base64Str The Base64 string.
  65. *
  66. * @return {WordArray} The word array.
  67. *
  68. * @static
  69. *
  70. * @example
  71. *
  72. * const wordArray = CryptoJS.enc.Base64.parse(base64String);
  73. */
  74. parse(base64Str) {
  75. // Shortcuts
  76. let base64StrLength = base64Str.length;
  77. const map = this._map;
  78. let reverseMap = this._reverseMap;
  79. if (!reverseMap) {
  80. this._reverseMap = [];
  81. reverseMap = this._reverseMap;
  82. for (let j = 0; j < map.length; j += 1) {
  83. reverseMap[map.charCodeAt(j)] = j;
  84. }
  85. }
  86. // Ignore padding
  87. const paddingChar = map.charAt(64);
  88. if (paddingChar) {
  89. const paddingIndex = base64Str.indexOf(paddingChar);
  90. if (paddingIndex !== -1) {
  91. base64StrLength = paddingIndex;
  92. }
  93. }
  94. // Convert
  95. return parseLoop(base64Str, base64StrLength, reverseMap);
  96. },
  97. _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
  98. };