Base64.mjs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**
  2. * Base64 functions.
  3. *
  4. * @author n1474335 [n1474335@gmail.com]
  5. * @copyright Crown Copyright 2016
  6. * @license Apache-2.0
  7. */
  8. import Utils from "../Utils";
  9. /**
  10. * Base64's the input byte array using the given alphabet, returning a string.
  11. *
  12. * @param {byteArray|Uint8Array|string} data
  13. * @param {string} [alphabet="A-Za-z0-9+/="]
  14. * @returns {string}
  15. *
  16. * @example
  17. * // returns "SGVsbG8="
  18. * toBase64([72, 101, 108, 108, 111]);
  19. *
  20. * // returns "SGVsbG8="
  21. * toBase64("Hello");
  22. */
  23. export function toBase64(data, alphabet="A-Za-z0-9+/=") {
  24. if (!data) return "";
  25. if (typeof data == "string") {
  26. data = Utils.strToByteArray(data);
  27. }
  28. alphabet = Utils.expandAlphRange(alphabet).join("");
  29. let output = "",
  30. chr1, chr2, chr3,
  31. enc1, enc2, enc3, enc4,
  32. i = 0;
  33. while (i < data.length) {
  34. chr1 = data[i++];
  35. chr2 = data[i++];
  36. chr3 = data[i++];
  37. enc1 = chr1 >> 2;
  38. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  39. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  40. enc4 = chr3 & 63;
  41. if (isNaN(chr2)) {
  42. enc3 = enc4 = 64;
  43. } else if (isNaN(chr3)) {
  44. enc4 = 64;
  45. }
  46. output += alphabet.charAt(enc1) + alphabet.charAt(enc2) +
  47. alphabet.charAt(enc3) + alphabet.charAt(enc4);
  48. }
  49. return output;
  50. }
  51. /**
  52. * UnBase64's the input string using the given alphabet, returning a byte array.
  53. *
  54. * @param {byteArray} data
  55. * @param {string} [alphabet="A-Za-z0-9+/="]
  56. * @param {string} [returnType="string"] - Either "string" or "byteArray"
  57. * @param {boolean} [removeNonAlphChars=true]
  58. * @returns {byteArray}
  59. *
  60. * @example
  61. * // returns "Hello"
  62. * fromBase64("SGVsbG8=");
  63. *
  64. * // returns [72, 101, 108, 108, 111]
  65. * fromBase64("SGVsbG8=", null, "byteArray");
  66. */
  67. export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true) {
  68. if (!data) {
  69. return returnType === "string" ? "" : [];
  70. }
  71. alphabet = Utils.expandAlphRange(alphabet).join("");
  72. const output = [];
  73. let chr1, chr2, chr3,
  74. enc1, enc2, enc3, enc4,
  75. i = 0;
  76. if (removeNonAlphChars) {
  77. const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
  78. data = data.replace(re, "");
  79. }
  80. while (i < data.length) {
  81. enc1 = alphabet.indexOf(data.charAt(i++));
  82. enc2 = alphabet.indexOf(data.charAt(i++) || "=");
  83. enc3 = alphabet.indexOf(data.charAt(i++) || "=");
  84. enc4 = alphabet.indexOf(data.charAt(i++) || "=");
  85. enc2 = enc2 === -1 ? 64 : enc2;
  86. enc3 = enc3 === -1 ? 64 : enc3;
  87. enc4 = enc4 === -1 ? 64 : enc4;
  88. chr1 = (enc1 << 2) | (enc2 >> 4);
  89. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  90. chr3 = ((enc3 & 3) << 6) | enc4;
  91. output.push(chr1);
  92. if (enc3 !== 64) {
  93. output.push(chr2);
  94. }
  95. if (enc4 !== 64) {
  96. output.push(chr3);
  97. }
  98. }
  99. return returnType === "string" ? Utils.byteArrayToUtf8(output) : output;
  100. }
  101. /**
  102. * Base64 alphabets.
  103. */
  104. export const ALPHABET_OPTIONS = [
  105. {name: "Standard: A-Za-z0-9+/=", value: "A-Za-z0-9+/="},
  106. {name: "URL safe: A-Za-z0-9-_", value: "A-Za-z0-9-_"},
  107. {name: "Filename safe: A-Za-z0-9+-=", value: "A-Za-z0-9+\\-="},
  108. {name: "itoa64: ./0-9A-Za-z=", value: "./0-9A-Za-z="},
  109. {name: "XML: A-Za-z0-9_.", value: "A-Za-z0-9_."},
  110. {name: "y64: A-Za-z0-9._-", value: "A-Za-z0-9._-"},
  111. {name: "z64: 0-9a-zA-Z+/=", value: "0-9a-zA-Z+/="},
  112. {name: "Radix-64: 0-9A-Za-z+/=", value: "0-9A-Za-z+/="},
  113. {name: "Uuencoding: [space]-_", value: " -_"},
  114. {name: "Xxencoding: +-0-9A-Za-z", value: "+\\-0-9A-Za-z"},
  115. {name: "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r", value: "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"},
  116. {name: "ROT13: N-ZA-Mn-za-m0-9+/=", value: "N-ZA-Mn-za-m0-9+/="},
  117. {name: "UNIX crypt: ./0-9A-Za-z", value: "./0-9A-Za-z"},
  118. ];