index.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. "use strict";
  2. /**
  3. * A minimal base64 implementation for number arrays.
  4. * @memberof util
  5. * @namespace
  6. */
  7. var base64 = exports;
  8. /**
  9. * Calculates the byte length of a base64 encoded string.
  10. * @param {string} string Base64 encoded string
  11. * @returns {number} Byte length
  12. */
  13. base64.length = function length(string) {
  14. var p = string.length;
  15. if (!p)
  16. return 0;
  17. var n = 0;
  18. while (--p % 4 > 1 && string.charAt(p) === "=")
  19. ++n;
  20. return Math.ceil(string.length * 3) / 4 - n;
  21. };
  22. // Base64 encoding table
  23. var b64 = new Array(64);
  24. // Base64 decoding table
  25. var s64 = new Array(123);
  26. // 65..90, 97..122, 48..57, 43, 47
  27. for (var i = 0; i < 64;)
  28. s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;
  29. /**
  30. * Encodes a buffer to a base64 encoded string.
  31. * @param {Uint8Array} buffer Source buffer
  32. * @param {number} start Source start
  33. * @param {number} end Source end
  34. * @returns {string} Base64 encoded string
  35. */
  36. base64.encode = function encode(buffer, start, end) {
  37. var parts = null,
  38. chunk = [];
  39. var i = 0, // output index
  40. j = 0, // goto index
  41. t; // temporary
  42. while (start < end) {
  43. var b = buffer[start++];
  44. switch (j) {
  45. case 0:
  46. chunk[i++] = b64[b >> 2];
  47. t = (b & 3) << 4;
  48. j = 1;
  49. break;
  50. case 1:
  51. chunk[i++] = b64[t | b >> 4];
  52. t = (b & 15) << 2;
  53. j = 2;
  54. break;
  55. case 2:
  56. chunk[i++] = b64[t | b >> 6];
  57. chunk[i++] = b64[b & 63];
  58. j = 0;
  59. break;
  60. }
  61. if (i > 8191) {
  62. (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
  63. i = 0;
  64. }
  65. }
  66. if (j) {
  67. chunk[i++] = b64[t];
  68. chunk[i++] = 61;
  69. if (j === 1)
  70. chunk[i++] = 61;
  71. }
  72. if (parts) {
  73. if (i)
  74. parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
  75. return parts.join("");
  76. }
  77. return String.fromCharCode.apply(String, chunk.slice(0, i));
  78. };
  79. var invalidEncoding = "invalid encoding";
  80. /**
  81. * Decodes a base64 encoded string to a buffer.
  82. * @param {string} string Source string
  83. * @param {Uint8Array} buffer Destination buffer
  84. * @param {number} offset Destination offset
  85. * @returns {number} Number of bytes written
  86. * @throws {Error} If encoding is invalid
  87. */
  88. base64.decode = function decode(string, buffer, offset) {
  89. var start = offset;
  90. var j = 0, // goto index
  91. t; // temporary
  92. for (var i = 0; i < string.length;) {
  93. var c = string.charCodeAt(i++);
  94. if (c === 61 && j > 1)
  95. break;
  96. if ((c = s64[c]) === undefined)
  97. throw Error(invalidEncoding);
  98. switch (j) {
  99. case 0:
  100. t = c;
  101. j = 1;
  102. break;
  103. case 1:
  104. buffer[offset++] = t << 2 | (c & 48) >> 4;
  105. t = c;
  106. j = 2;
  107. break;
  108. case 2:
  109. buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2;
  110. t = c;
  111. j = 3;
  112. break;
  113. case 3:
  114. buffer[offset++] = (t & 3) << 6 | c;
  115. j = 0;
  116. break;
  117. }
  118. }
  119. if (j === 1)
  120. throw Error(invalidEncoding);
  121. return offset - start;
  122. };
  123. /**
  124. * Tests if the specified string appears to be base64 encoded.
  125. * @param {string} string String to test
  126. * @returns {boolean} `true` if probably base64 encoded, otherwise false
  127. */
  128. base64.test = function test(string) {
  129. return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string);
  130. };