File size: 5,290 Bytes
2bdf3d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
[![CI via GitHub Actions](https://github.com/dankogai/js-base64/actions/workflows/node.js.yml/badge.svg)](https://github.com/dankogai/js-base64/actions/workflows/node.js.yml)

# base64.js

Yet another [Base64] transcoder.

[Base64]: http://en.wikipedia.org/wiki/Base64

## Install

```shell
$ npm install --save js-base64
```

## Usage

### In Browser

Locally…

```html
<script src="base64.js"></script>
```

… or Directly from CDN.  In which case you don't even need to install.

```html
<script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.8/base64.min.js"></script>
```

This good old way loads `Base64` in the global context (`window`).  Though `Base64.noConflict()` is made available, you should consider using ES6 Module to avoid tainting `window`.

### As an ES6 Module

locally…

```javascript
import { Base64 } from 'js-base64';
```

```javascript
// or if you prefer no Base64 namespace
import { encode, decode } from 'js-base64';
```

or even remotely.

```html
<script type="module">
// note jsdelivr.net does not automatically minify .mjs
import { Base64 } from 'https://cdn.jsdelivr.net/npm/js-base64@3.7.8/base64.mjs';
</script>
```

```html
<script type="module">
// or if you prefer no Base64 namespace
import { encode, decode } from 'https://cdn.jsdelivr.net/npm/js-base64@3.7.8/base64.mjs';
</script>
```

### node.js (commonjs)

```javascript
const {Base64} = require('js-base64');
```

Unlike the case above, the global context is no longer modified.

You can also use [esm] to `import` instead of `require`.

[esm]: https://github.com/standard-things/esm

```javascript
require=require('esm')(module);
import {Base64} from 'js-base64';
```

## SYNOPSIS

```javascript
let latin = 'dankogai';
let utf8  = '小飼弾'
let u8s   =  new Uint8Array([100,97,110,107,111,103,97,105]);
Base64.encode(latin);             // ZGFua29nYWk=
Base64.encode(latin, true);       // ZGFua29nYWk skips padding
Base64.encodeURI(latin);          // ZGFua29nYWk
Base64.btoa(latin);               // ZGFua29nYWk=
Base64.btoa(utf8);                // raises exception
Base64.fromUint8Array(u8s);       // ZGFua29nYWk=
Base64.fromUint8Array(u8s, true); // ZGFua29nYW which is URI safe
Base64.encode(utf8);              // 5bCP6aO85by+
Base64.encode(utf8, true)         // 5bCP6aO85by-
Base64.encodeURI(utf8);           // 5bCP6aO85by-
```

```javascript
Base64.decode(      'ZGFua29nYWk=');// dankogai
Base64.decode(      'ZGFua29nYWk'); // dankogai
Base64.atob(        'ZGFua29nYWk=');// dankogai
Base64.atob(        '5bCP6aO85by+');// '小飼弾' which is nonsense
Base64.toUint8Array('ZGFua29nYWk=');// u8s above
Base64.decode(      '5bCP6aO85by+');// 小飼弾
// note .decodeURI() is unnecessary since it accepts both flavors
Base64.decode(      '5bCP6aO85by-');// 小飼弾
```

```javascript
Base64.isValid(0);      // false: 0 is not string
Base64.isValid('');     // true: a valid Base64-encoded empty byte
Base64.isValid('ZA=='); // true: a valid Base64-encoded 'd'
Base64.isValid('Z A='); // true: whitespaces are okay
Base64.isValid('ZA');   // true: padding ='s can be omitted
Base64.isValid('++');   // true: can be non URL-safe
Base64.isValid('--');   // true: or URL-safe
Base64.isValid('+-');   // false: can't mix both
```

### Built-in Extensions

By default `Base64` leaves built-in prototypes untouched.  But you can extend them as below.

```javascript
// you have to explicitly extend String.prototype
Base64.extendString();
// once extended, you can do the following
'dankogai'.toBase64();        // ZGFua29nYWk=
'小飼弾'.toBase64();           // 5bCP6aO85by+
'小飼弾'.toBase64(true);       // 5bCP6aO85by-
'小飼弾'.toBase64URI();        // 5bCP6aO85by- ab alias of .toBase64(true)
'小飼弾'.toBase64URL();        // 5bCP6aO85by- an alias of .toBase64URI()
'ZGFua29nYWk='.fromBase64();  // dankogai
'5bCP6aO85by+'.fromBase64();  // 小飼弾
'5bCP6aO85by-'.fromBase64();  // 小飼弾
'5bCP6aO85by-'.toUint8Array();// u8s above
```

```javascript
// you have to explicitly extend Uint8Array.prototype
Base64.extendUint8Array();
// once extended, you can do the following
u8s.toBase64();     // 'ZGFua29nYWk='
u8s.toBase64URI();  // 'ZGFua29nYWk'
u8s.toBase64URL();  // 'ZGFua29nYWk' an alias of .toBase64URI()
```

```javascript
// extend all at once
Base64.extendBuiltins()
```

## `.decode()` vs `.atob` (and `.encode()` vs `btoa()`)

Suppose you have:

```
var pngBase64 = 
  "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
```

Which is a Base64-encoded 1x1 transparent PNG, **DO NOT USE** `Base64.decode(pngBase64)`.  Use `Base64.atob(pngBase64)` instead.  `Base64.decode()` decodes to UTF-8 string while `Base64.atob()` decodes to bytes, which is compatible to browser built-in `atob()` (Which is absent in node.js).  The same rule applies to the opposite direction.

Or even better, `Base64.toUint8Array(pngBase64)`.

## Brief History

* Since version 3.3 it is written in TypeScript.  Now `base64.mjs` is compiled from `base64.ts` then `base64.js` is generated from `base64.mjs`.
* Since version 3.7 `base64.js` is ES5-compatible again (hence IE11-compatible).
* Since 3.0 `js-base64` switch to ES2015 module so it is no longer compatible with legacy browsers like IE (see above)