Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. 'use strict';
  2. /**
  3. * Implementation of atob() according to the HTML spec, except that instead of
  4. * throwing INVALID_CHARACTER_ERR we return null.
  5. */
  6. function atob(input) {
  7. // WebIDL requires DOMStrings to just be converted using ECMAScript
  8. // ToString, which in our case amounts to calling String().
  9. input = String(input);
  10. // "Remove all space characters from input."
  11. input = input.replace(/[ \t\n\f\r]/g, '');
  12. // "If the length of input divides by 4 leaving no remainder, then: if
  13. // input ends with one or two U+003D EQUALS SIGN (=) characters, remove
  14. // them from input."
  15. if (input.length % 4 == 0 && /==?$/.test(input)) {
  16. input = input.replace(/==?$/, '');
  17. }
  18. // "If the length of input divides by 4 leaving a remainder of 1, throw an
  19. // INVALID_CHARACTER_ERR exception and abort these steps."
  20. //
  21. // "If input contains a character that is not in the following list of
  22. // characters and character ranges, throw an INVALID_CHARACTER_ERR
  23. // exception and abort these steps:
  24. //
  25. // U+002B PLUS SIGN (+)
  26. // U+002F SOLIDUS (/)
  27. // U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9)
  28. // U+0041 LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z
  29. // U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z"
  30. if (input.length % 4 == 1 || !/^[+/0-9A-Za-z]*$/.test(input)) {
  31. return null;
  32. }
  33. // "Let output be a string, initially empty."
  34. var output = '';
  35. // "Let buffer be a buffer that can have bits appended to it, initially
  36. // empty."
  37. //
  38. // We append bits via left-shift and or. accumulatedBits is used to track
  39. // when we've gotten to 24 bits.
  40. var buffer = 0;
  41. var accumulatedBits = 0;
  42. // "While position does not point past the end of input, run these
  43. // substeps:"
  44. for (var i = 0; i < input.length; i++) {
  45. // "Find the character pointed to by position in the first column of
  46. // the following table. Let n be the number given in the second cell of
  47. // the same row."
  48. //
  49. // "Append to buffer the six bits corresponding to number, most
  50. // significant bit first."
  51. //
  52. // atobLookup() implements the table from the spec.
  53. buffer <<= 6;
  54. buffer |= atobLookup(input[i]);
  55. // "If buffer has accumulated 24 bits, interpret them as three 8-bit
  56. // big-endian numbers. Append the three characters with code points
  57. // equal to those numbers to output, in the same order, and then empty
  58. // buffer."
  59. accumulatedBits += 6;
  60. if (accumulatedBits == 24) {
  61. output += String.fromCharCode((buffer & 0xff0000) >> 16);
  62. output += String.fromCharCode((buffer & 0xff00) >> 8);
  63. output += String.fromCharCode(buffer & 0xff);
  64. buffer = accumulatedBits = 0;
  65. }
  66. // "Advance position by one character."
  67. }
  68. // "If buffer is not empty, it contains either 12 or 18 bits. If it
  69. // contains 12 bits, discard the last four and interpret the remaining
  70. // eight as an 8-bit big-endian number. If it contains 18 bits, discard the
  71. // last two and interpret the remaining 16 as two 8-bit big-endian numbers.
  72. // Append the one or two characters with code points equal to those one or
  73. // two numbers to output, in the same order."
  74. if (accumulatedBits == 12) {
  75. buffer >>= 4;
  76. output += String.fromCharCode(buffer);
  77. } else if (accumulatedBits == 18) {
  78. buffer >>= 2;
  79. output += String.fromCharCode((buffer & 0xff00) >> 8);
  80. output += String.fromCharCode(buffer & 0xff);
  81. }
  82. // "Return output."
  83. return output;
  84. }
  85. /**
  86. * A lookup table for atob(), which converts an ASCII character to the
  87. * corresponding six-bit number.
  88. */
  89. function atobLookup(chr) {
  90. if (/[A-Z]/.test(chr)) {
  91. return chr.charCodeAt(0) - 'A'.charCodeAt(0);
  92. }
  93. if (/[a-z]/.test(chr)) {
  94. return chr.charCodeAt(0) - 'a'.charCodeAt(0) + 26;
  95. }
  96. if (/[0-9]/.test(chr)) {
  97. return chr.charCodeAt(0) - '0'.charCodeAt(0) + 52;
  98. }
  99. if (chr == '+') {
  100. return 62;
  101. }
  102. if (chr == '/') {
  103. return 63;
  104. }
  105. // Throw exception; should not be hit in tests
  106. }
  107. module.exports = atob;