├── .editorconfig
├── .gitattributes
├── .gitignore
├── .travis.yml
├── Gruntfile.js
├── LICENSE-MIT.txt
├── README.md
├── base64.js
├── package.json
├── scripts
└── export-data.js
├── src
└── base64.js
└── tests
└── tests.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = tab
6 | end_of_line = lf
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | [{README.md,*.yml}]
11 | indent_style = space
12 | indent_size = 2
13 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Automatically normalize line endings for all text-based files
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Coverage report
2 | coverage
3 |
4 | # Installed npm modules
5 | node_modules
6 |
7 | # Folder view configuration files
8 | .DS_Store
9 | Desktop.ini
10 |
11 | # Thumbnail cache files
12 | ._*
13 | Thumbs.db
14 |
15 | # Files that might appear on external disks
16 | .Spotlight-V100
17 | .Trashes
18 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "10"
4 | - "12"
5 | before_script:
6 | - "npm install -g grunt-cli"
7 | script:
8 | - "grunt ci"
9 | after_script:
10 | - "grunt shell:cover-coveralls"
11 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | grunt.initConfig({
4 | 'shell': {
5 | 'options': {
6 | 'stdout': true,
7 | 'stderr': true,
8 | 'failOnError': true
9 | },
10 | 'cover-html': {
11 | 'command': 'istanbul cover --report "html" --verbose --dir "coverage" "tests/tests.js"'
12 | },
13 | 'cover-coveralls': {
14 | 'command': 'istanbul cover --verbose --dir "coverage" "tests/tests.js" && coveralls < coverage/lcov.info; rm -rf coverage/lcov*'
15 | },
16 | 'test-node': {
17 | 'command': 'echo "Testing in Node..."; npm test'
18 | },
19 | 'test-browser': {
20 | 'command': 'echo "Testing in a browser..."; open "tests/index.html"; open "tests/index.html?norequire=true"'
21 | }
22 | },
23 | 'template': {
24 | 'build': {
25 | 'options': {
26 | 'data': function() {
27 | return require('./scripts/export-data.js');
28 | }
29 | },
30 | 'files': {
31 | 'base64.js': ['src/base64.js']
32 | }
33 | }
34 | }
35 | });
36 |
37 | grunt.loadNpmTasks('grunt-shell');
38 | grunt.loadNpmTasks('grunt-template');
39 |
40 | grunt.registerTask('cover', 'shell:cover-html');
41 | grunt.registerTask('ci', [
42 | 'template',
43 | 'shell:test-node'
44 | ]);
45 | grunt.registerTask('test', [
46 | 'ci',
47 | 'shell:test-browser'
48 | ]);
49 |
50 | grunt.registerTask('fetch', [
51 | 'shell:fetch',
52 | 'build'
53 | ]);
54 |
55 | grunt.registerTask('build', [
56 | 'default'
57 | ]);
58 |
59 | grunt.registerTask('default', [
60 | 'template',
61 | 'shell:test-node'
62 | ]);
63 |
64 | };
65 |
--------------------------------------------------------------------------------
/LICENSE-MIT.txt:
--------------------------------------------------------------------------------
1 | Copyright Mathias Bynens
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # base64 [](https://travis-ci.org/mathiasbynens/base64) [](https://coveralls.io/r/mathiasbynens/base64)
2 |
3 | _base64_ is a robust base64 encoder/decoder that is fully compatible with [`atob()` and `btoa()`](https://html.spec.whatwg.org/multipage/webappapis.html#atob), written in JavaScript. The base64-encoding and -decoding algorithms it uses are fully [RFC 4648](https://tools.ietf.org/html/rfc4648#section-4) compliant.
4 |
5 | ## Installation
6 |
7 | Via [npm](https://www.npmjs.com/):
8 |
9 | ```bash
10 | npm install base-64
11 | ```
12 |
13 | In a browser:
14 |
15 | ```html
16 |
17 | ```
18 |
19 | In [Narwhal](http://narwhaljs.org/), [Node.js](https://nodejs.org/), and [RingoJS](http://ringojs.org/):
20 |
21 | ```js
22 | var base64 = require('base-64');
23 | ```
24 |
25 | In [Rhino](http://www.mozilla.org/rhino/):
26 |
27 | ```js
28 | load('base64.js');
29 | ```
30 |
31 | Using an AMD loader like [RequireJS](http://requirejs.org/):
32 |
33 | ```js
34 | require(
35 | {
36 | 'paths': {
37 | 'base64': 'path/to/base64'
38 | }
39 | },
40 | ['base64'],
41 | function(base64) {
42 | console.log(base64);
43 | }
44 | );
45 | ```
46 |
47 | ## API
48 |
49 | ### `base64.version`
50 |
51 | A string representing the semantic version number.
52 |
53 | ### `base64.encode(input)`
54 |
55 | This function takes a byte string (the `input` parameter) and encodes it according to base64. The input data must be in the form of a string containing only characters in the range from U+0000 to U+00FF, each representing a binary byte with values `0x00` to `0xFF`. The `base64.encode()` function is designed to be fully compatible with [`btoa()` as described in the HTML Standard](https://html.spec.whatwg.org/multipage/webappapis.html#dom-windowbase64-btoa).
56 |
57 | ```js
58 | var encodedData = base64.encode(input);
59 | ```
60 |
61 | To base64-encode any Unicode string, [encode it as UTF-8 first](https://github.com/mathiasbynens/utf8.js#utf8encodestring):
62 |
63 | ```js
64 | var base64 = require('base-64');
65 | var utf8 = require('utf8');
66 |
67 | var text = 'foo © bar 𝌆 baz';
68 | var bytes = utf8.encode(text);
69 | var encoded = base64.encode(bytes);
70 | console.log(encoded);
71 | // → 'Zm9vIMKpIGJhciDwnYyGIGJheg=='
72 | ```
73 |
74 | ### `base64.decode(input)`
75 |
76 | This function takes a base64-encoded string (the `input` parameter) and decodes it. The return value is in the form of a string containing only characters in the range from U+0000 to U+00FF, each representing a binary byte with values `0x00` to `0xFF`. The `base64.decode()` function is designed to be fully compatible with [`atob()` as described in the HTML Standard](https://html.spec.whatwg.org/multipage/webappapis.html#dom-windowbase64-atob).
77 |
78 | ```js
79 | var decodedData = base64.decode(encodedData);
80 | ```
81 |
82 | To base64-decode UTF-8-encoded data back into a Unicode string, [UTF-8-decode it](https://github.com/mathiasbynens/utf8.js#utf8decodebytestring) after base64-decoding it:
83 |
84 | ```js
85 | var encoded = 'Zm9vIMKpIGJhciDwnYyGIGJheg==';
86 | var bytes = base64.decode(encoded);
87 | var text = utf8.decode(bytes);
88 | console.log(text);
89 | // → 'foo © bar 𝌆 baz'
90 | ```
91 |
92 | ## Support
93 |
94 | _base64_ is designed to work in at least Node.js v0.10.0, Narwhal 0.3.2, RingoJS 0.8-0.9, PhantomJS 1.9.0, Rhino 1.7RC4, as well as old and modern versions of Chrome, Firefox, Safari, Opera, and Internet Explorer.
95 |
96 | ## Unit tests & code coverage
97 |
98 | After cloning this repository, run `npm install` to install the dependencies needed for development and testing. You may want to install Istanbul _globally_ using `npm install istanbul -g`.
99 |
100 | Once that’s done, you can run the unit tests in Node using `npm test` or `node tests/tests.js`. To run the tests in Rhino, Ringo, Narwhal, and web browsers as well, use `grunt test`.
101 |
102 | To generate the code coverage report, use `grunt cover`.
103 |
104 | ## Author
105 |
106 | | [](https://twitter.com/mathias "Follow @mathias on Twitter") |
107 | |---|
108 | | [Mathias Bynens](https://mathiasbynens.be/) |
109 |
110 | ## License
111 |
112 | _base64_ is available under the [MIT](https://mths.be/mit) license.
113 |
--------------------------------------------------------------------------------
/base64.js:
--------------------------------------------------------------------------------
1 | /*! https://mths.be/base64 v1.0.0 by @mathias | MIT license */
2 | ;(function(root) {
3 |
4 | // Detect free variables `exports`.
5 | var freeExports = typeof exports == 'object' && exports;
6 |
7 | // Detect free variable `module`.
8 | var freeModule = typeof module == 'object' && module &&
9 | module.exports == freeExports && module;
10 |
11 | // Detect free variable `global`, from Node.js or Browserified code, and use
12 | // it as `root`.
13 | var freeGlobal = typeof global == 'object' && global;
14 | if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
15 | root = freeGlobal;
16 | }
17 |
18 | /*--------------------------------------------------------------------------*/
19 |
20 | var InvalidCharacterError = function(message) {
21 | this.message = message;
22 | };
23 | InvalidCharacterError.prototype = new Error;
24 | InvalidCharacterError.prototype.name = 'InvalidCharacterError';
25 |
26 | var error = function(message) {
27 | // Note: the error messages used throughout this file match those used by
28 | // the native `atob`/`btoa` implementation in Chromium.
29 | throw new InvalidCharacterError(message);
30 | };
31 |
32 | var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
33 | // http://whatwg.org/html/common-microsyntaxes.html#space-character
34 | var REGEX_SPACE_CHARACTERS = /[\t\n\f\r ]/g;
35 |
36 | // `decode` is designed to be fully compatible with `atob` as described in the
37 | // HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob
38 | // The optimized base64-decoding algorithm used is based on @atk’s excellent
39 | // implementation. https://gist.github.com/atk/1020396
40 | var decode = function(input) {
41 | input = String(input)
42 | .replace(REGEX_SPACE_CHARACTERS, '');
43 | var length = input.length;
44 | if (length % 4 == 0) {
45 | input = input.replace(/==?$/, '');
46 | length = input.length;
47 | }
48 | if (
49 | length % 4 == 1 ||
50 | // http://whatwg.org/C#alphanumeric-ascii-characters
51 | /[^+a-zA-Z0-9/]/.test(input)
52 | ) {
53 | error(
54 | 'Invalid character: the string to be decoded is not correctly encoded.'
55 | );
56 | }
57 | var bitCounter = 0;
58 | var bitStorage;
59 | var buffer;
60 | var output = '';
61 | var position = -1;
62 | while (++position < length) {
63 | buffer = TABLE.indexOf(input.charAt(position));
64 | bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;
65 | // Unless this is the first of a group of 4 characters…
66 | if (bitCounter++ % 4) {
67 | // …convert the first 8 bits to a single ASCII character.
68 | output += String.fromCharCode(
69 | 0xFF & bitStorage >> (-2 * bitCounter & 6)
70 | );
71 | }
72 | }
73 | return output;
74 | };
75 |
76 | // `encode` is designed to be fully compatible with `btoa` as described in the
77 | // HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa
78 | var encode = function(input) {
79 | input = String(input);
80 | if (/[^\0-\xFF]/.test(input)) {
81 | // Note: no need to special-case astral symbols here, as surrogates are
82 | // matched, and the input is supposed to only contain ASCII anyway.
83 | error(
84 | 'The string to be encoded contains characters outside of the ' +
85 | 'Latin1 range.'
86 | );
87 | }
88 | var padding = input.length % 3;
89 | var output = '';
90 | var position = -1;
91 | var a;
92 | var b;
93 | var c;
94 | var buffer;
95 | // Make sure any padding is handled outside of the loop.
96 | var length = input.length - padding;
97 |
98 | while (++position < length) {
99 | // Read three bytes, i.e. 24 bits.
100 | a = input.charCodeAt(position) << 16;
101 | b = input.charCodeAt(++position) << 8;
102 | c = input.charCodeAt(++position);
103 | buffer = a + b + c;
104 | // Turn the 24 bits into four chunks of 6 bits each, and append the
105 | // matching character for each of them to the output.
106 | output += (
107 | TABLE.charAt(buffer >> 18 & 0x3F) +
108 | TABLE.charAt(buffer >> 12 & 0x3F) +
109 | TABLE.charAt(buffer >> 6 & 0x3F) +
110 | TABLE.charAt(buffer & 0x3F)
111 | );
112 | }
113 |
114 | if (padding == 2) {
115 | a = input.charCodeAt(position) << 8;
116 | b = input.charCodeAt(++position);
117 | buffer = a + b;
118 | output += (
119 | TABLE.charAt(buffer >> 10) +
120 | TABLE.charAt((buffer >> 4) & 0x3F) +
121 | TABLE.charAt((buffer << 2) & 0x3F) +
122 | '='
123 | );
124 | } else if (padding == 1) {
125 | buffer = input.charCodeAt(position);
126 | output += (
127 | TABLE.charAt(buffer >> 2) +
128 | TABLE.charAt((buffer << 4) & 0x3F) +
129 | '=='
130 | );
131 | }
132 |
133 | return output;
134 | };
135 |
136 | var base64 = {
137 | 'encode': encode,
138 | 'decode': decode,
139 | 'version': '1.0.0'
140 | };
141 |
142 | // Some AMD build optimizers, like r.js, check for specific condition patterns
143 | // like the following:
144 | if (
145 | typeof define == 'function' &&
146 | typeof define.amd == 'object' &&
147 | define.amd
148 | ) {
149 | define(function() {
150 | return base64;
151 | });
152 | } else if (freeExports && !freeExports.nodeType) {
153 | if (freeModule) { // in Node.js or RingoJS v0.8.0+
154 | freeModule.exports = base64;
155 | } else { // in Narwhal or RingoJS v0.7.0-
156 | for (var key in base64) {
157 | base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);
158 | }
159 | }
160 | } else { // in Rhino or a web browser
161 | root.base64 = base64;
162 | }
163 |
164 | }(this));
165 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "base-64",
3 | "version": "1.0.0",
4 | "description": "A robust base64 encoder/decoder that is fully compatible with `atob()` and `btoa()`, written in JavaScript.",
5 | "homepage": "https://mths.be/base64",
6 | "main": "base64.js",
7 | "keywords": [
8 | "codec",
9 | "decoder",
10 | "encoder",
11 | "base64",
12 | "atob",
13 | "btoa"
14 | ],
15 | "license": "MIT",
16 | "author": {
17 | "name": "Mathias Bynens",
18 | "url": "https://mathiasbynens.be/"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/mathiasbynens/base64.git"
23 | },
24 | "bugs": "https://github.com/mathiasbynens/base64/issues",
25 | "files": [
26 | "LICENSE-MIT.txt",
27 | "base64.js"
28 | ],
29 | "scripts": {
30 | "test": "mocha tests/tests.js",
31 | "build": "grunt build"
32 | },
33 | "devDependencies": {
34 | "coveralls": "^2.11.4",
35 | "grunt": "^0.4.5",
36 | "grunt-cli": "^1.3.2",
37 | "grunt-shell": "^1.1.2",
38 | "grunt-template": "^0.2.3",
39 | "istanbul": "^0.4.0",
40 | "mocha": "^6.2.0",
41 | "regenerate": "^1.2.1"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/scripts/export-data.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var regenerate = require('regenerate');
3 |
4 | // http://whatwg.org/html/common-microsyntaxes.html#space-character
5 | var spaceCharacters = regenerate(
6 | 0x0020, // U+0020 SPACE
7 | 0x0009, // U+0009 CHARACTER TABULATION (tab)
8 | 0x000A, // U+000A LINE FEED (LF)
9 | 0x000C, // U+000C FORM FEED (FF)
10 | 0x000D // U+000D CARRIAGE RETURN (CR)
11 | );
12 |
13 | module.exports = {
14 | 'spaceCharacters': spaceCharacters.toString(),
15 | 'version': JSON.parse(fs.readFileSync('package.json', 'utf-8')).version
16 | };
17 |
--------------------------------------------------------------------------------
/src/base64.js:
--------------------------------------------------------------------------------
1 | /*! https://mths.be/base64 v<%= version %> by @mathias | MIT license */
2 | ;(function(root) {
3 |
4 | // Detect free variables `exports`.
5 | var freeExports = typeof exports == 'object' && exports;
6 |
7 | // Detect free variable `module`.
8 | var freeModule = typeof module == 'object' && module &&
9 | module.exports == freeExports && module;
10 |
11 | // Detect free variable `global`, from Node.js or Browserified code, and use
12 | // it as `root`.
13 | var freeGlobal = typeof global == 'object' && global;
14 | if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
15 | root = freeGlobal;
16 | }
17 |
18 | /*--------------------------------------------------------------------------*/
19 |
20 | var InvalidCharacterError = function(message) {
21 | this.message = message;
22 | };
23 | InvalidCharacterError.prototype = new Error;
24 | InvalidCharacterError.prototype.name = 'InvalidCharacterError';
25 |
26 | var error = function(message) {
27 | // Note: the error messages used throughout this file match those used by
28 | // the native `atob`/`btoa` implementation in Chromium.
29 | throw new InvalidCharacterError(message);
30 | };
31 |
32 | var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
33 | // http://whatwg.org/html/common-microsyntaxes.html#space-character
34 | var REGEX_SPACE_CHARACTERS = /<%= spaceCharacters %>/g;
35 |
36 | // `decode` is designed to be fully compatible with `atob` as described in the
37 | // HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob
38 | // The optimized base64-decoding algorithm used is based on @atk’s excellent
39 | // implementation. https://gist.github.com/atk/1020396
40 | var decode = function(input) {
41 | input = String(input)
42 | .replace(REGEX_SPACE_CHARACTERS, '');
43 | var length = input.length;
44 | if (length % 4 == 0) {
45 | input = input.replace(/==?$/, '');
46 | length = input.length;
47 | }
48 | if (
49 | length % 4 == 1 ||
50 | // http://whatwg.org/C#alphanumeric-ascii-characters
51 | /[^+a-zA-Z0-9/]/.test(input)
52 | ) {
53 | error(
54 | 'Invalid character: the string to be decoded is not correctly encoded.'
55 | );
56 | }
57 | var bitCounter = 0;
58 | var bitStorage;
59 | var buffer;
60 | var output = '';
61 | var position = -1;
62 | while (++position < length) {
63 | buffer = TABLE.indexOf(input.charAt(position));
64 | bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;
65 | // Unless this is the first of a group of 4 characters…
66 | if (bitCounter++ % 4) {
67 | // …convert the first 8 bits to a single ASCII character.
68 | output += String.fromCharCode(
69 | 0xFF & bitStorage >> (-2 * bitCounter & 6)
70 | );
71 | }
72 | }
73 | return output;
74 | };
75 |
76 | // `encode` is designed to be fully compatible with `btoa` as described in the
77 | // HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa
78 | var encode = function(input) {
79 | input = String(input);
80 | if (/[^\0-\xFF]/.test(input)) {
81 | // Note: no need to special-case astral symbols here, as surrogates are
82 | // matched, and the input is supposed to only contain ASCII anyway.
83 | error(
84 | 'The string to be encoded contains characters outside of the ' +
85 | 'Latin1 range.'
86 | );
87 | }
88 | var padding = input.length % 3;
89 | var output = '';
90 | var position = -1;
91 | var a;
92 | var b;
93 | var c;
94 | var buffer;
95 | // Make sure any padding is handled outside of the loop.
96 | var length = input.length - padding;
97 |
98 | while (++position < length) {
99 | // Read three bytes, i.e. 24 bits.
100 | a = input.charCodeAt(position) << 16;
101 | b = input.charCodeAt(++position) << 8;
102 | c = input.charCodeAt(++position);
103 | buffer = a + b + c;
104 | // Turn the 24 bits into four chunks of 6 bits each, and append the
105 | // matching character for each of them to the output.
106 | output += (
107 | TABLE.charAt(buffer >> 18 & 0x3F) +
108 | TABLE.charAt(buffer >> 12 & 0x3F) +
109 | TABLE.charAt(buffer >> 6 & 0x3F) +
110 | TABLE.charAt(buffer & 0x3F)
111 | );
112 | }
113 |
114 | if (padding == 2) {
115 | a = input.charCodeAt(position) << 8;
116 | b = input.charCodeAt(++position);
117 | buffer = a + b;
118 | output += (
119 | TABLE.charAt(buffer >> 10) +
120 | TABLE.charAt((buffer >> 4) & 0x3F) +
121 | TABLE.charAt((buffer << 2) & 0x3F) +
122 | '='
123 | );
124 | } else if (padding == 1) {
125 | buffer = input.charCodeAt(position);
126 | output += (
127 | TABLE.charAt(buffer >> 2) +
128 | TABLE.charAt((buffer << 4) & 0x3F) +
129 | '=='
130 | );
131 | }
132 |
133 | return output;
134 | };
135 |
136 | var base64 = {
137 | 'encode': encode,
138 | 'decode': decode,
139 | 'version': '<%= version %>'
140 | };
141 |
142 | // Some AMD build optimizers, like r.js, check for specific condition patterns
143 | // like the following:
144 | if (
145 | typeof define == 'function' &&
146 | typeof define.amd == 'object' &&
147 | define.amd
148 | ) {
149 | define(function() {
150 | return base64;
151 | });
152 | } else if (freeExports && !freeExports.nodeType) {
153 | if (freeModule) { // in Node.js or RingoJS v0.8.0+
154 | freeModule.exports = base64;
155 | } else { // in Narwhal or RingoJS v0.7.0-
156 | for (var key in base64) {
157 | base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);
158 | }
159 | }
160 | } else { // in Rhino or a web browser
161 | root.base64 = base64;
162 | }
163 |
164 | }(this));
165 |
--------------------------------------------------------------------------------
/tests/tests.js:
--------------------------------------------------------------------------------
1 | const base64 = require('../base64.js');
2 |
3 | const assert = require('assert');
4 |
5 | describe('base64.encode', function() {
6 | it('should work', function() {
7 | assert.equal(
8 | base64.encode('\0\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F'),
9 | 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8=',
10 | 'All possible octets'
11 | );
12 | assert.equal(
13 | base64.encode('a'),
14 | 'YQ==',
15 | 'Two padding characters'
16 | );
17 | assert.equal(
18 | base64.encode('aa'),
19 | 'YWE=',
20 | 'One padding character'
21 | );
22 | assert.equal(
23 | base64.encode('aaa'),
24 | 'YWFh',
25 | 'No padding characters'
26 | );
27 | assert.equal(
28 | base64.encode('foo\0'),
29 | 'Zm9vAA==',
30 | 'U+0000'
31 | );
32 | assert.equal(
33 | base64.encode('foo\0\0'),
34 | 'Zm9vAAA=',
35 | 'U+0000'
36 | );
37 | // Tests from https://tools.ietf.org/html/rfc4648#section-10
38 | assert.equal(
39 | base64.encode(''),
40 | '',
41 | 'empty string'
42 | );
43 | assert.equal(
44 | base64.encode('f'),
45 | 'Zg=='
46 | );
47 | assert.equal(
48 | base64.encode('fo'),
49 | 'Zm8='
50 | );
51 | assert.equal(
52 | base64.encode('foo'),
53 | 'Zm9v'
54 | );
55 | assert.equal(
56 | base64.encode('foob'),
57 | 'Zm9vYg=='
58 | );
59 | assert.equal(
60 | base64.encode('fooba'),
61 | 'Zm9vYmE='
62 | );
63 | assert.equal(
64 | base64.encode('foobar'),
65 | 'Zm9vYmFy'
66 | );
67 | // Tests from https://github.com/w3c/web-platform-tests/blob/master/html/webappapis/atob/base64.html
68 | assert.throws(
69 | function() {
70 | base64.encode('\u05E2\u05D1\u05E8\u05D9\u05EA');
71 | }
72 | );
73 | assert.equal(
74 | (function() {
75 | try {
76 | base64.encode('\u05E2\u05D1\u05E8\u05D9\u05EA');
77 | } catch (exception) {
78 | return exception.name;
79 | }
80 | }()),
81 | 'InvalidCharacterError'
82 | );
83 | assert.equal(
84 | base64.encode('\xFF\xFF\xC0'),
85 | '///A'
86 | );
87 | assert.equal(
88 | base64.encode('\0'),
89 | 'AA=='
90 | );
91 | assert.equal(
92 | base64.encode('\0a'),
93 | 'AGE='
94 | );
95 | assert.equal(
96 | base64.encode(undefined),
97 | 'dW5kZWZpbmVk'
98 | );
99 | assert.equal(
100 | base64.encode(null),
101 | 'bnVsbA=='
102 | );
103 | assert.equal(
104 | base64.encode(7),
105 | 'Nw=='
106 | );
107 | assert.equal(
108 | base64.encode(1.5),
109 | 'MS41'
110 | );
111 | assert.equal(
112 | base64.encode(true),
113 | 'dHJ1ZQ=='
114 | );
115 | assert.equal(
116 | base64.encode(false),
117 | 'ZmFsc2U='
118 | );
119 | assert.equal(
120 | base64.encode(NaN),
121 | 'TmFO'
122 | );
123 | assert.equal(
124 | base64.encode(-Infinity),
125 | 'LUluZmluaXR5'
126 | );
127 | assert.equal(
128 | base64.encode(+Infinity),
129 | 'SW5maW5pdHk='
130 | );
131 | assert.equal(
132 | base64.encode(-0),
133 | 'MA=='
134 | );
135 | assert.equal(
136 | base64.encode(+0),
137 | 'MA=='
138 | );
139 | assert.equal(
140 | base64.encode({ 'toString': function() { return 'foo'; } }),
141 | 'Zm9v'
142 | );
143 | assert.throws(
144 | function() {
145 | base64.encode({ 'toString': function() { throw new RangeError(); } });
146 | },
147 | RangeError
148 | );
149 | assert.throws(
150 | function() {
151 | base64.encode('\uD800\uDC00');
152 | }
153 | );
154 | assert.equal(
155 | (function() {
156 | try {
157 | base64.encode('\uD800\uDC00');
158 | } catch (exception) {
159 | return exception.name;
160 | }
161 | }()),
162 | 'InvalidCharacterError'
163 | );
164 | });
165 | });
166 |
167 | describe('base64.decode', function() {
168 | it('should work', function() {
169 | assert.equal(
170 | base64.decode('AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8='),
171 | '\0\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F',
172 | 'All possible octets'
173 | );
174 | assert.equal(
175 | base64.decode('AAECA\t\n\f\r wQFBgcICQoLDA0ODx\t\n\f\r AREhMUFRYXGBkaGxwdHh8gIS\t\n\f\r IjJCUmJygpKissLS4vMDEyMzQ1Njc4OT\t\n\f\r o7PD0+P0BBQkNERUZHSElKS0xNT\t\n\f\r k9QUVJTVFVWV1hZWltcXV5fY\t\n\f\r GFiY2RlZmdoaWprbG\t\n\f\r 1ub3BxcnN0dXZ3eH\t\n\f\r l6e3x9fn8='),
176 | '\0\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F',
177 | 'HTML space characters must be stripped before decoding'
178 | );
179 | assert.throws(
180 | function() {
181 | base64.decode('YQ===');
182 | },
183 | /Invalid character/,
184 | 'Invalid character'
185 | );
186 | assert.equal(
187 | (function() {
188 | try {
189 | base64.decode('YQ===');
190 | } catch (exception) {
191 | return exception.name;
192 | }
193 | }()),
194 | 'InvalidCharacterError',
195 | 'The string to be decoded is not correctly encoded.'
196 | );
197 | assert.equal(
198 | base64.decode('YQ=='),
199 | 'a',
200 | 'Two padding characters'
201 | );
202 | assert.equal(
203 | base64.decode('YWE='),
204 | 'aa',
205 | 'One padding character'
206 | );
207 | assert.equal(
208 | base64.decode('YWFh'),
209 | 'aaa',
210 | 'No padding characters'
211 | );
212 | assert.equal(
213 | base64.decode('YQ'),
214 | 'a',
215 | 'Discarded bits'
216 | );
217 | assert.equal(
218 | base64.decode('YR'),
219 | 'a',
220 | 'Discarded bits'
221 | );
222 | assert.equal(
223 | base64.decode('Zm9vIGJhciBiYXo='),
224 | 'foo bar baz',
225 | 'One-character padding `=`'
226 | );
227 | assert.equal(
228 | base64.decode('Zm9vIGJhcg=='),
229 | 'foo bar',
230 | 'Two-character padding `==`'
231 | );
232 | assert.equal(
233 | base64.decode('Zm9v'),
234 | 'foo',
235 | 'No padding'
236 | );
237 | assert.equal(
238 | base64.decode('Zm9vAA=='),
239 | 'foo\0',
240 | 'U+0000'
241 | );
242 | assert.equal(
243 | base64.decode('Zm9vAAA='),
244 | 'foo\0\0',
245 | 'U+0000'
246 | );
247 | // Tests from https://github.com/w3c/web-platform-tests/blob/master/html/webappapis/atob/base64.html
248 | assert.equal(
249 | base64.decode(''),
250 | ''
251 | );
252 | assert.equal(
253 | base64.decode('abcd'),
254 | 'i\xB7\x1D'
255 | );
256 | assert.equal(
257 | base64.decode(' abcd'),
258 | 'i\xB7\x1D'
259 | );
260 | assert.equal(
261 | base64.decode('abcd '),
262 | 'i\xB7\x1D'
263 | );
264 | assert.throws(
265 | function() {
266 | base64.decode('abcd===');
267 | }
268 | );
269 | assert.equal(
270 | (function() {
271 | try {
272 | base64.decode('abcd===');
273 | } catch (exception) {
274 | return exception.name;
275 | }
276 | }()),
277 | 'InvalidCharacterError',
278 | );
279 | assert.throws(
280 | function() {
281 | base64.decode(' abcd===');
282 | }
283 | );
284 | assert.equal(
285 | (function() {
286 | try {
287 | base64.decode(' abcd===');
288 | } catch (exception) {
289 | return exception.name;
290 | }
291 | }()),
292 | 'InvalidCharacterError'
293 | );
294 | assert.throws(
295 | function() {
296 | base64.decode('abcd=== ');
297 | }
298 | );
299 | assert.equal(
300 | (function() {
301 | try {
302 | base64.decode('abcd=== ');
303 | } catch (exception) {
304 | return exception.name;
305 | }
306 | }()),
307 | 'InvalidCharacterError'
308 | );
309 | assert.throws(
310 | function() {
311 | base64.decode('abcd ===');
312 | }
313 | );
314 | assert.equal(
315 | (function() {
316 | try {
317 | base64.decode('abcd ===');
318 | } catch (exception) {
319 | return exception.name;
320 | }
321 | }()),
322 | 'InvalidCharacterError'
323 | );
324 | assert.throws(
325 | function() {
326 | base64.decode('a');
327 | }
328 | );
329 | assert.equal(
330 | (function() {
331 | try {
332 | base64.decode('a');
333 | } catch (exception) {
334 | return exception.name;
335 | }
336 | }()),
337 | 'InvalidCharacterError'
338 | );
339 | assert.equal(
340 | base64.decode('ab'),
341 | 'i'
342 | );
343 | assert.equal(
344 | base64.decode('abc'),
345 | 'i\xB7'
346 | );
347 | assert.throws(
348 | function() {
349 | base64.decode('abcde');
350 | }
351 | );
352 | assert.equal(
353 | (function() {
354 | try {
355 | base64.decode('abcde');
356 | } catch (exception) {
357 | return exception.name;
358 | }
359 | }()),
360 | 'InvalidCharacterError'
361 | );
362 | assert.throws(
363 | function() {
364 | base64.decode('\uD800\uDC00');
365 | }
366 | );
367 | assert.equal(
368 | (function() {
369 | try {
370 | base64.decode('\uD800\uDC00');
371 | } catch (exception) {
372 | return exception.name;
373 | }
374 | }()),
375 | 'InvalidCharacterError'
376 | );
377 | assert.throws(
378 | function() {
379 | base64.decode('=');
380 | }
381 | );
382 | assert.equal(
383 | (function() {
384 | try {
385 | base64.decode('=');
386 | } catch (exception) {
387 | return exception.name;
388 | }
389 | }()),
390 | 'InvalidCharacterError'
391 | );
392 | assert.throws(
393 | function() {
394 | base64.decode('==');
395 | }
396 | );
397 | assert.equal(
398 | (function() {
399 | try {
400 | base64.decode('==');
401 | } catch (exception) {
402 | return exception.name;
403 | }
404 | }()),
405 | 'InvalidCharacterError'
406 | );
407 | assert.throws(
408 | function() {
409 | base64.decode('===');
410 | }
411 | );
412 | assert.equal(
413 | (function() {
414 | try {
415 | base64.decode('===');
416 | } catch (exception) {
417 | return exception.name;
418 | }
419 | }()),
420 | 'InvalidCharacterError'
421 | );
422 | assert.throws(
423 | function() {
424 | base64.decode('====');
425 | },
426 | );
427 | assert.equal(
428 | (function() {
429 | try {
430 | base64.decode('====');
431 | } catch (exception) {
432 | return exception.name;
433 | }
434 | }()),
435 | 'InvalidCharacterError'
436 | );
437 | assert.throws(
438 | function() {
439 | base64.decode('=====');
440 | }
441 | );
442 | assert.equal(
443 | (function() {
444 | try {
445 | base64.decode('=====');
446 | } catch (exception) {
447 | return exception.name;
448 | }
449 | }()),
450 | 'InvalidCharacterError'
451 | );
452 | assert.throws(
453 | function() {
454 | base64.decode('a=');
455 | }
456 | );
457 | assert.equal(
458 | (function() {
459 | try {
460 | base64.decode('a=');
461 | } catch (exception) {
462 | return exception.name;
463 | }
464 | }()),
465 | 'InvalidCharacterError'
466 | );
467 | assert.throws(
468 | function() {
469 | base64.decode('a==');
470 | }
471 | );
472 | assert.equal(
473 | (function() {
474 | try {
475 | base64.decode('a==');
476 | } catch (exception) {
477 | return exception.name;
478 | }
479 | }()),
480 | 'InvalidCharacterError'
481 | );
482 | assert.throws(
483 | function() {
484 | base64.decode('a===');
485 | }
486 | );
487 | assert.equal(
488 | (function() {
489 | try {
490 | base64.decode('a===');
491 | } catch (exception) {
492 | return exception.name;
493 | }
494 | }()),
495 | 'InvalidCharacterError'
496 | );
497 | assert.throws(
498 | function() {
499 | base64.decode('a====');
500 | }
501 | );
502 | assert.equal(
503 | (function() {
504 | try {
505 | base64.decode('a====');
506 | } catch (exception) {
507 | return exception.name;
508 | }
509 | }()),
510 | 'InvalidCharacterError'
511 | );
512 | assert.throws(
513 | function() {
514 | base64.decode('a=====');
515 | }
516 | );
517 | assert.equal(
518 | (function() {
519 | try {
520 | base64.decode('a=====');
521 | } catch (exception) {
522 | return exception.name;
523 | }
524 | }()),
525 | 'InvalidCharacterError'
526 | );
527 | assert.throws(
528 | function() {
529 | base64.decode('ab=');
530 | }
531 | );
532 | assert.equal(
533 | (function() {
534 | try {
535 | base64.decode('ab=');
536 | } catch (exception) {
537 | return exception.name;
538 | }
539 | }()),
540 | 'InvalidCharacterError'
541 | );
542 | assert.equal(
543 | base64.decode('ab=='),
544 | 'i'
545 | );
546 | assert.throws(
547 | function() {
548 | base64.decode('ab===');
549 | }
550 | );
551 | assert.equal(
552 | (function() {
553 | try {
554 | base64.decode('ab===');
555 | } catch (exception) {
556 | return exception.name;
557 | }
558 | }()),
559 | 'InvalidCharacterError'
560 | );
561 | assert.throws(
562 | function() {
563 | base64.decode('ab====');
564 | }
565 | );
566 | assert.equal(
567 | (function() {
568 | try {
569 | base64.decode('ab====');
570 | } catch (exception) {
571 | return exception.name;
572 | }
573 | }()),
574 | 'InvalidCharacterError'
575 | );
576 | assert.throws(
577 | function() {
578 | base64.decode('ab=====');
579 | }
580 | );
581 | assert.equal(
582 | (function() {
583 | try {
584 | base64.decode('ab=====');
585 | } catch (exception) {
586 | return exception.name;
587 | }
588 | }()),
589 | 'InvalidCharacterError'
590 | );
591 | assert.equal(
592 | base64.decode('abc='),
593 | 'i\xB7'
594 | );
595 | assert.throws(
596 | function() {
597 | base64.decode('abc==');
598 | }
599 | );
600 | assert.equal(
601 | (function() {
602 | try {
603 | base64.decode('abc==');
604 | } catch (exception) {
605 | return exception.name;
606 | }
607 | }()),
608 | 'InvalidCharacterError',
609 | );
610 | assert.throws(
611 | function() {
612 | base64.decode('abc===');
613 | }
614 | );
615 | assert.equal(
616 | (function() {
617 | try {
618 | base64.decode('abc===');
619 | } catch (exception) {
620 | return exception.name;
621 | }
622 | }()),
623 | 'InvalidCharacterError'
624 | );
625 | assert.throws(
626 | function() {
627 | base64.decode('abc====');
628 | }
629 | );
630 | assert.equal(
631 | (function() {
632 | try {
633 | base64.decode('abc====');
634 | } catch (exception) {
635 | return exception.name;
636 | }
637 | }()),
638 | 'InvalidCharacterError'
639 | );
640 | assert.throws(
641 | function() {
642 | base64.decode('abc=====');
643 | }
644 | );
645 | assert.equal(
646 | (function() {
647 | try {
648 | base64.decode('abc=====');
649 | } catch (exception) {
650 | return exception.name;
651 | }
652 | }()),
653 | 'InvalidCharacterError'
654 | );
655 | assert.throws(
656 | function() {
657 | base64.decode('abcd=');
658 | }
659 | );
660 | assert.equal(
661 | (function() {
662 | try {
663 | base64.decode('abcd=');
664 | } catch (exception) {
665 | return exception.name;
666 | }
667 | }()),
668 | 'InvalidCharacterError'
669 | );
670 | assert.throws(
671 | function() {
672 | base64.decode('abcd==');
673 | }
674 | );
675 | assert.equal(
676 | (function() {
677 | try {
678 | base64.decode('abcd==');
679 | } catch (exception) {
680 | return exception.name;
681 | }
682 | }()),
683 | 'InvalidCharacterError'
684 | );
685 | assert.throws(
686 | function() {
687 | base64.decode('abcd===');
688 | }
689 | );
690 | assert.equal(
691 | (function() {
692 | try {
693 | base64.decode('abcd===');
694 | } catch (exception) {
695 | return exception.name;
696 | }
697 | }()),
698 | 'InvalidCharacterError'
699 | );
700 | assert.throws(
701 | function() {
702 | base64.decode('abcd====');
703 | }
704 | );
705 | assert.equal(
706 | (function() {
707 | try {
708 | base64.decode('abcd====');
709 | } catch (exception) {
710 | return exception.name;
711 | }
712 | }()),
713 | 'InvalidCharacterError'
714 | );
715 | assert.throws(
716 | function() {
717 | base64.decode('abcd=====');
718 | }
719 | );
720 | assert.equal(
721 | (function() {
722 | try {
723 | base64.decode('abcd=====');
724 | } catch (exception) {
725 | return exception.name;
726 | }
727 | }()),
728 | 'InvalidCharacterError'
729 | );
730 | assert.throws(
731 | function() {
732 | base64.decode('abcde=');
733 | }
734 | );
735 | assert.equal(
736 | (function() {
737 | try {
738 | base64.decode('abcde=');
739 | } catch (exception) {
740 | return exception.name;
741 | }
742 | }()),
743 | 'InvalidCharacterError'
744 | );
745 | assert.throws(
746 | function() {
747 | base64.decode('abcde==');
748 | }
749 | );
750 | assert.equal(
751 | (function() {
752 | try {
753 | base64.decode('abcde==');
754 | } catch (exception) {
755 | return exception.name;
756 | }
757 | }()),
758 | 'InvalidCharacterError'
759 | );
760 | assert.throws(
761 | function() {
762 | base64.decode('abcde===');
763 | }
764 | );
765 | assert.equal(
766 | (function() {
767 | try {
768 | base64.decode('abcde===');
769 | } catch (exception) {
770 | return exception.name;
771 | }
772 | }()),
773 | 'InvalidCharacterError'
774 | );
775 | assert.throws(
776 | function() {
777 | base64.decode('abcde====');
778 | }
779 | );
780 | assert.equal(
781 | (function() {
782 | try {
783 | base64.decode('abcde====');
784 | } catch (exception) {
785 | return exception.name;
786 | }
787 | }()),
788 | 'InvalidCharacterError'
789 | );
790 | assert.throws(
791 | function() {
792 | base64.decode('abcde=====');
793 | }
794 | );
795 | assert.equal(
796 | (function() {
797 | try {
798 | base64.decode('abcde=====');
799 | } catch (exception) {
800 | return exception.name;
801 | }
802 | }()),
803 | 'InvalidCharacterError'
804 | );
805 | assert.throws(
806 | function() {
807 | base64.decode('=a');
808 | }
809 | );
810 | assert.equal(
811 | (function() {
812 | try {
813 | base64.decode('=a');
814 | } catch (exception) {
815 | return exception.name;
816 | }
817 | }()),
818 | 'InvalidCharacterError'
819 | );
820 | assert.throws(
821 | function() {
822 | base64.decode('=a=');
823 | }
824 | );
825 | assert.equal(
826 | (function() {
827 | try {
828 | base64.decode('=a=');
829 | } catch (exception) {
830 | return exception.name;
831 | }
832 | }()),
833 | 'InvalidCharacterError'
834 | );
835 | assert.throws(
836 | function() {
837 | base64.decode('a=b');
838 | }
839 | );
840 | assert.equal(
841 | (function() {
842 | try {
843 | base64.decode('a=b');
844 | } catch (exception) {
845 | return exception.name;
846 | }
847 | }()),
848 | 'InvalidCharacterError'
849 | );
850 | assert.throws(
851 | function() {
852 | base64.decode('a=b=');
853 | }
854 | );
855 | assert.equal(
856 | (function() {
857 | try {
858 | base64.decode('a=b=');
859 | } catch (exception) {
860 | return exception.name;
861 | }
862 | }()),
863 | 'InvalidCharacterError'
864 | );
865 | assert.throws(
866 | function() {
867 | base64.decode('ab=c');
868 | }
869 | );
870 | assert.equal(
871 | (function() {
872 | try {
873 | base64.decode('ab=c');
874 | } catch (exception) {
875 | return exception.name;
876 | }
877 | }()),
878 | 'InvalidCharacterError'
879 | );
880 | assert.throws(
881 | function() {
882 | base64.decode('ab=c=');
883 | }
884 | );
885 | assert.equal(
886 | (function() {
887 | try {
888 | base64.decode('ab=c=');
889 | } catch (exception) {
890 | return exception.name;
891 | }
892 | }()),
893 | 'InvalidCharacterError'
894 | );
895 | assert.throws(
896 | function() {
897 | base64.decode('abc=d');
898 | }
899 | );
900 | assert.equal(
901 | (function() {
902 | try {
903 | base64.decode('abc=d');
904 | } catch (exception) {
905 | return exception.name;
906 | }
907 | }()),
908 | 'InvalidCharacterError'
909 | );
910 | assert.throws(
911 | function() {
912 | base64.decode('abc=d=');
913 | }
914 | );
915 | assert.equal(
916 | (function() {
917 | try {
918 | base64.decode('abc=d=');
919 | } catch (exception) {
920 | return exception.name;
921 | }
922 | }()),
923 | 'InvalidCharacterError'
924 | );
925 | assert.equal(
926 | base64.decode('ab\tcd'),
927 | 'i\xB7\x1D'
928 | );
929 | assert.equal(
930 | base64.decode('ab\ncd'),
931 | 'i\xB7\x1D'
932 | );
933 | assert.equal(
934 | base64.decode('ab\fcd'),
935 | 'i\xB7\x1D'
936 | );
937 | assert.equal(
938 | base64.decode('ab\rcd'),
939 | 'i\xB7\x1D'
940 | );
941 | assert.equal(
942 | base64.decode('ab cd'),
943 | 'i\xB7\x1D'
944 | );
945 | assert.throws(
946 | function() {
947 | base64.decode('ab\xA0cd');
948 | }
949 | );
950 | assert.equal(
951 | (function() {
952 | try {
953 | base64.decode('ab\xA0cd');
954 | } catch (exception) {
955 | return exception.name;
956 | }
957 | }()),
958 | 'InvalidCharacterError'
959 | );
960 | assert.equal(
961 | base64.decode('ab\t\n\f\r cd'),
962 | 'i\xB7\x1D'
963 | );
964 | assert.equal(
965 | base64.decode(' \t\n\f\r ab\t\n\f\r cd\t\n\f\r '),
966 | 'i\xB7\x1D'
967 | );
968 | assert.equal(
969 | base64.decode('ab\t\n\f\r =\t\n\f\r =\t\n\f\r '),
970 | 'i'
971 | );
972 | assert.throws(
973 | function() {
974 | base64.decode('A');
975 | }
976 | );
977 | assert.equal(
978 | (function() {
979 | try {
980 | base64.decode('A');
981 | } catch (exception) {
982 | return exception.name;
983 | }
984 | }()),
985 | 'InvalidCharacterError'
986 | );
987 | assert.equal(
988 | base64.decode('/A'),
989 | '\xFC'
990 | );
991 | assert.equal(
992 | base64.decode('//A'),
993 | '\xFF\xF0'
994 | );
995 | assert.equal(
996 | base64.decode('///A'),
997 | '\xFF\xFF\xC0'
998 | );
999 | assert.throws(
1000 | function() {
1001 | base64.decode('////A');
1002 | }
1003 | );
1004 | assert.equal(
1005 | (function() {
1006 | try {
1007 | base64.decode('////A');
1008 | } catch (exception) {
1009 | return exception.name;
1010 | }
1011 | }()),
1012 | 'InvalidCharacterError'
1013 | );
1014 | assert.throws(
1015 | function() {
1016 | base64.decode('/');
1017 | }
1018 | );
1019 | assert.equal(
1020 | (function() {
1021 | try {
1022 | base64.decode('/');
1023 | } catch (exception) {
1024 | return exception.name;
1025 | }
1026 | }()),
1027 | 'InvalidCharacterError'
1028 | );
1029 | assert.equal(
1030 | base64.decode('A/'),
1031 | '\x03'
1032 | );
1033 | assert.equal(
1034 | base64.decode('AA/'),
1035 | '\0\x0F'
1036 | );
1037 | assert.throws(
1038 | function() {
1039 | base64.decode('AAAA/');
1040 | }
1041 | );
1042 | assert.equal(
1043 | (function() {
1044 | try {
1045 | base64.decode('AAAA/');
1046 | } catch (exception) {
1047 | return exception.name;
1048 | }
1049 | }()),
1050 | 'InvalidCharacterError'
1051 | );
1052 | assert.equal(
1053 | base64.decode('AAA/'),
1054 | '\0\0?'
1055 | );
1056 | assert.throws(
1057 | function() {
1058 | base64.decode('\0');
1059 | }
1060 | );
1061 | assert.equal(
1062 | (function() {
1063 | try {
1064 | base64.decode('\0');
1065 | } catch (exception) {
1066 | return exception.name;
1067 | }
1068 | }()),
1069 | 'InvalidCharacterError'
1070 | );
1071 | assert.throws(
1072 | function() {
1073 | base64.decode('\0nonsense');
1074 | }
1075 | );
1076 | assert.equal(
1077 | (function() {
1078 | try {
1079 | base64.decode('\0nonsense');
1080 | } catch (exception) {
1081 | return exception.name;
1082 | }
1083 | }()),
1084 | 'InvalidCharacterError'
1085 | );
1086 | assert.throws(
1087 | function() {
1088 | base64.decode('abcd\0nonsense');
1089 | }
1090 | );
1091 | assert.equal(
1092 | (function() {
1093 | try {
1094 | base64.decode('abcd\0nonsense');
1095 | } catch (exception) {
1096 | return exception.name;
1097 | }
1098 | }()),
1099 | 'InvalidCharacterError'
1100 | );
1101 | assert.throws(
1102 | function() {
1103 | base64.decode(undefined);
1104 | }
1105 | );
1106 | assert.equal(
1107 | (function() {
1108 | try {
1109 | base64.decode(undefined);
1110 | } catch (exception) {
1111 | return exception.name;
1112 | }
1113 | }()),
1114 | 'InvalidCharacterError'
1115 | );
1116 | assert.equal(
1117 | base64.decode(null),
1118 | '\x9E\xE9e'
1119 | );
1120 | assert.throws(
1121 | function() {
1122 | base64.decode(7);
1123 | }
1124 | );
1125 | assert.equal(
1126 | (function() {
1127 | try {
1128 | base64.decode(7);
1129 | } catch (exception) {
1130 | return exception.name;
1131 | }
1132 | }()),
1133 | 'InvalidCharacterError'
1134 | );
1135 | assert.equal(
1136 | base64.decode(12),
1137 | '\xD7'
1138 | );
1139 | assert.throws(
1140 | function() {
1141 | base64.decode(1.5);
1142 | }
1143 | );
1144 | assert.equal(
1145 | (function() {
1146 | try {
1147 | base64.decode(1.5);
1148 | } catch (exception) {
1149 | return exception.name;
1150 | }
1151 | }()),
1152 | 'InvalidCharacterError'
1153 | );
1154 | assert.equal(
1155 | base64.decode(true),
1156 | '\xB6\xBB\x9E'
1157 | );
1158 | assert.throws(
1159 | function() {
1160 | base64.decode(false);
1161 | }
1162 | );
1163 | assert.equal(
1164 | (function() {
1165 | try {
1166 | base64.decode(false);
1167 | } catch (exception) {
1168 | return exception.name;
1169 | }
1170 | }()),
1171 | 'InvalidCharacterError'
1172 | );
1173 | assert.equal(
1174 | base64.decode(NaN),
1175 | '5\xA3'
1176 | );
1177 | assert.equal(
1178 | base64.decode(+Infinity),
1179 | '"w\xE2\x9E+r'
1180 | );
1181 | assert.throws(
1182 | function() {
1183 | base64.decode(-Infinity);
1184 | }
1185 | );
1186 | assert.equal(
1187 | (function() {
1188 | try {
1189 | base64.decode(-Infinity);
1190 | } catch (exception) {
1191 | return exception.name;
1192 | }
1193 | }()),
1194 | 'InvalidCharacterError'
1195 | );
1196 | assert.throws(
1197 | function() {
1198 | base64.decode(+0);
1199 | }
1200 | );
1201 | assert.equal(
1202 | (function() {
1203 | try {
1204 | base64.decode(+0);
1205 | } catch (exception) {
1206 | return exception.name;
1207 | }
1208 | }()),
1209 | 'InvalidCharacterError'
1210 | );
1211 | assert.throws(
1212 | function() {
1213 | base64.decode(-0);
1214 | }
1215 | );
1216 | assert.equal(
1217 | (function() {
1218 | try {
1219 | base64.decode(-0);
1220 | } catch (exception) {
1221 | return exception.name;
1222 | }
1223 | }()),
1224 | 'InvalidCharacterError'
1225 | );
1226 | assert.equal(
1227 | base64.decode({ 'toString': function() { return 'foo'; }}),
1228 | '~\x8A'
1229 | );
1230 | assert.equal(
1231 | base64.decode({ 'toString': function() { return 'abcd'; }}),
1232 | 'i\xB7\x1D'
1233 | );
1234 | });
1235 | });
1236 |
--------------------------------------------------------------------------------