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
|
---
title: Кодирование и декодирование в формате Base64
slug: Glossary/Base64
translation_of: Glossary/Base64
original_slug: Web/API/WindowBase64/Base64_encoding_and_decoding
---
<p><strong>Base64</strong> - это группа схожих <a href="https://en.wikipedia.org/wiki/Binary-to-text_encoding">binary-to-text encoding</a> схем, которые представляют двоичные данные в ASCII-формате методом перевода в radix-64 представление. Термин <em>Base64</em> происходит от a specific <a href="https://en.wikipedia.org/wiki/MIME#Content-Transfer-Encoding">MIME content transfer encoding</a>.</p>
<p>Кодирование Base64 широко используется в случаях, когда требуется перекодировать двоичные данные для передачи по каналу приспособленному для передачи текстовых данных. Это делается с целью защиты двоичных данных от любых возможных повреждений при передаче. Base64 широко используется во многих приложениях, включая электронную почту (<a href="https://en.wikipedia.org/wiki/MIME">MIME</a>), и при сохранении больших объёмов данных в <a href="/en-US/docs/XML">XML</a>.</p>
<p>В языке JavaScript существуют две функции, для кодирования и декодирования данных в/из формат Base64 соответственно:</p>
<ul>
<li>{{domxref("WindowBase64.btoa","btoa()")}}</li>
<li>{{domxref("WindowBase64.atob","atob()")}}</li>
</ul>
<p><code><font face="Arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">Функция </span></font>atob()</code> декодирует Base64-кодированную строку. В противоположность ей, функция <code>btoa()</code> создаёт Base64 кодированную ASCII строку из "строки" бинарных данных.</p>
<p>Обе функции <code>atob()</code> и <code>btoa()</code> работают со строками. Если вам необходимо работать с <a href="/en-US/docs/Web/API/ArrayBuffer"><code>ArrayBuffers</code></a>, обратитесь к <a href="#">этому параграфу</a>.</p>
<table class="topicpage-table">
<tbody>
<tr>
<td>
<h2 class="Documentation" id="Documentation" name="Documentation">Документация</h2>
<dl>
<dt><a href="https://developer.mozilla.org/en-US/docs/data_URIs" title="https://developer.mozilla.org/en-US/docs/data_URIs"><code>data</code> URIs</a></dt>
<dd><small><code>data</code> URIs, описанные в <a class="external" href="http://tools.ietf.org/html/rfc2397">RFC 2397</a>, позволяют создателям контента встроить в документ маленькие файлы в виде строки (инлайном).</small></dd>
<dt><a href="https://en.wikipedia.org/wiki/Base64">Base64</a></dt>
<dd><small>Wikipedia article about Base64 encoding.</small></dd>
<dt>{{domxref("WindowBase64.atob","atob()")}}</dt>
<dd><small>Decodes a string of data which has been encoded using base-64 encoding.</small></dd>
<dt>{{domxref("WindowBase64.btoa","btoa()")}}</dt>
<dd><small>Creates a base-64 encoded ASCII string from a "string" of binary data.</small></dd>
<dt><a href="#The_Unicode_Problem">The "Unicode Problem"</a></dt>
<dd><small>In most browsers, calling <code>btoa()</code> on a Unicode string will cause a <code>Character Out Of Range</code> exception. This paragraph shows some solutions.</small></dd>
<dt><a href="/en-US/docs/URIScheme" title="/en-US/docs/URIScheme">URIScheme</a></dt>
<dd><small>List of Mozilla supported URI schemes</small></dd>
<dt><a href="/en-US/docs/Web/JavaScript/Typed_arrays/StringView" title="/en-US/docs/Web/JavaScript/Typed_arrays/StringView"><code>StringView</code></a></dt>
<dd>In this article is published a library of ours whose aims are:
<ul>
<li>creating a <a class="external" href="http://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>-like interface for strings (i.e. array of characters codes —<a href="/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBufferView" title="/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBufferView"> <code>ArrayBufferView</code></a> in JavaScript) based upon the JavaScript <a href="/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBuffer" title="/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBuffer"><code>ArrayBuffer</code></a> interface,</li>
<li>creating a collection of methods for such string-like objects (since now: <code>stringView</code>s) which work <strong>strictly on array of numbers</strong> rather than on immutable JavaScript strings,</li>
<li>working with other Unicode encodings, different from default JavaScript's UTF-16 <a href="/en-US/docs/Web/API/DOMString" title="/en-US/docs/Web/API/DOMString"><code>DOMString</code></a>s,</li>
</ul>
</dd>
</dl>
</td>
<td>
<h2 class="Tools" id="Tools" name="Tools">Tools</h2>
<ul>
<li><a href="#Solution_2_–_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8">Rewriting <code>atob()</code> and <code>btoa()</code> using <code>TypedArray</code>s and UTF-8</a></li>
<li><a href="/en-US/docs/Web/JavaScript/Typed_arrays/StringView" title="/en-US/docs/Web/JavaScript/Typed_arrays/StringView"><code>StringView</code> – a C-like representation of strings based on typed arrays</a></li>
</ul>
<h2 class="Related_Topics" id="Related_Topics" name="Related_Topics">Related Topics</h2>
<ul>
<li><a href="/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBuffer"><code>ArrayBuffer</code></a></li>
<li><a href="/en-US/docs/Web/JavaScript/Typed_arrays">Typed arrays</a></li>
<li><code><a href="/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBufferView">ArrayBufferView</a></code></li>
<li><a href="/en-US/docs/Web/JavaScript/Typed_arrays/Uint8Array"><code>Uint8Array</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/StringView" title="/en-US/docs/Web/JavaScript/Typed_arrays/StringView"><code>StringView</code> – a C-like representation of strings based on typed arrays</a></li>
<li><a href="/en-US/docs/Web/API/DOMString" title="/en-US/docs/Web/API/DOMString"><code>DOMString</code></a></li>
<li><a href="/en-US/docs/URI" title="/en-US/docs/URI"><code>URI</code></a></li>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI"><code>encodeURI()</code></a></li>
</ul>
</td>
</tr>
</tbody>
</table>
<h2 id="The_Unicode_Problem">The "Unicode Problem"</h2>
<p>Since <a href="/en-US/docs/Web/API/DOMString" title="/en-US/docs/Web/API/DOMString"><code>DOMString</code></a>s are 16-bit-encoded strings, in most browsers calling <code>window.btoa</code> on a Unicode string will cause a <code>Character Out Of Range</code> exception if a character exceeds the range of a 8-bit byte (0x00~0xFF). There are two possible methods to solve this problem:</p>
<ul>
<li>the first one is to escape the whole string (with UTF-8, see {{jsxref("encodeURIComponent")}}) and then encode it;</li>
<li>the second one is to convert the UTF-16 <a href="/en-US/docs/Web/API/DOMString" title="/en-US/docs/Web/API/DOMString"><code>DOMString</code></a> to an UTF-8 array of characters and then encode it.</li>
</ul>
<p>Here are the two possible methods.</p>
<h3 id="Solution_1_–_escaping_the_string_before_encoding_it">Solution #1 – escaping the string before encoding it</h3>
<pre class="brush:js">function b64EncodeUnicode(str) {
// first we use encodeURIComponent to get percent-encoded UTF-8,
// then we convert the percent encodings into raw bytes which
// can be fed into btoa.
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64EncodeUnicode('\n'); // "Cg=="
</pre>
<p>To decode the Base64-encoded value back into a String:</p>
<pre class="brush: js">function b64DecodeUnicode(str) {
// Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
b64DecodeUnicode('Cg=='); // "\n"
</pre>
<p><a href="https://github.com/coolaj86/unibabel-js">Unibabel</a> implements common conversions using this strategy.</p>
<h3 id="Solution_2_–_rewrite_the_DOMs_atob_and_btoa_using_JavaScripts_TypedArrays_and_UTF-8">Solution #2 – rewrite the DOMs <code>atob()</code> and <code>btoa()</code> using JavaScript's <code>TypedArray</code>s and UTF-8</h3>
<p>Use a <a href="/en-US/docs/Web/API/TextEncoder">TextEncoder</a> polyfill such as <a href="https://github.com/inexorabletash/text-encoding">TextEncoding</a> (also includes legacy windows, mac, and ISO encodings), <a href="https://github.com/coolaj86/TextEncoderLite">TextEncoderLite</a>, combined with a <a href="https://github.com/feross/buffer">Buffer</a> and a Base64 implementation such as <a href="https://github.com/beatgammit/base64-js">base64-js</a>.</p>
<p>When a native <code>TextEncoder</code> implementation is not available, the most light-weight solution would be to use <a href="https://github.com/coolaj86/TextEncoderLite">TextEncoderLite</a> with <a href="https://github.com/beatgammit/base64-js">base64-js</a>. Use the browser implementation when you can.</p>
<p>The following function implements such a strategy. It assumes base64-js imported as <code><script type="text/javascript" src="base64js.min.js"/></code>. Note that TextEncoderLite only works with UTF-8.</p>
<pre class="brush: js">function Base64Encode(str, encoding = 'utf-8') {
var bytes = new (TextEncoder || TextEncoderLite)(encoding).encode(str);
return base64js.fromByteArray(bytes);
}
function Base64Decode(str, encoding = 'utf-8') {
var bytes = base64js.toByteArray(str);
return new (TextDecoder || TextDecoderLite)(encoding).decode(bytes);
}
</pre>
|