У меня есть сценарий PHP, который может кодировать изображение PNG в строку Base64.
Я бы хотел сделать то же самое с помощью JavaScript. Я знаю, как открывать файлы, но не знаю, как их кодировать. Я не привык работать с двоичными данными.
Вот лучший способ base64_encode и base64_decode с использованием javascript. См. Ссылки ниже. phpjs.org/functions/base64_encode:358phpjs.org/functions/base64_decode:357
Проверить microjs: microjs.com/#base64
Упоминается в мета-вопросе Практически одинаковые ответы - Единственное отличие: исправление ошибок.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
Кроме того, поиск по "кодировка javascript base64" открывает множество других вариантов, указанное выше было первым.
Это также полезно, когда кодировка base64 нестандартна; в моем случае не использовался символ «/» и знак «?» Вместо этого использовался символ, то есть даже в Chrome atob () не собирался декодировать входящие строки base64.
Будьте осторожны с этим кодом - он пытается интерпретировать вашу строку как строку в кодировке UTF-8. У нас был случай, когда у нас была двоичная строка (т.е. каждый символ в строке должен интерпретироваться как байт), и этот код действительно испортил данные. Прочти источник, Люк.
Если вы используете код из webtoolkito info, не забывайте об авторских правах: / ** * * Кодирование / декодирование Base64 * webtoolkit.info * ** /
Все, что необходимо для обеспечения безопасности большинства двоичных кодировок / декодирований, - это удалить сомнительный оператор string = string.replace(/\r\n/g,"\n"); в методе кодирования utf8.
Я бы использовал описанный выше метод с небольшим объемом данных. Для больших файлов лучше рассмотреть многостраничный POST, когда файл передается как двоичный.
@Marius: Мне интересно, почему они вообще включили string = string.replace(/\r\n/g,"\n");, лол. Это похоже на «о, давайте закодируем эту строку, но сначала почему бы нам просто случайно не нормализовать все разрывы строк без всякой уважительной причины». Это должно быть исключено из класса при любых обстоятельствах.
Я знаю, что Base64 предназначен для других целей и имеет накладные расходы 33%. Можно ли оптимизировать это для Интернета? Итак, когда у вас есть изображение со 100 байтами, оно сохраняется в строковой форме как 100 байтов вместо примерно 133 байтов?
@Triynko, когда люди слепо внедряют решения отсюда, даже немного не проверяя, то они, вероятно, получают то, что заслуживают. (не совсем, я не против помогать людям, но я могу только надеяться, что они хотя бы прочитают эти комментарии!)
Я не гуру javascript, но этот код, похоже, содержит ошибку: если chr2 равно NaN, его значение по-прежнему используется в операторе enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);. В моем браузере это работает нормально, NaN>>4 равен 0, но я не знаю, все ли браузеры это делают (также NaN/16 равно NaN).
@Triynko: Сегодня я обнаружил, что на меня повлияла та строчка, которая превращала "\ r \ n" в "\ n". Мне определенно потребовалось время, чтобы заподозрить, что функция кодирования base 64 искажает мои строки!
input.charCodeAt(i++) всегда возвращает 65535 для символов от 128 (10000000) -255 (11111111) в IE9!
Заставить все сообщество использовать линейную сложность вместо постоянной (при декодировании) - довольно неортодоксальная вещь;)
добавьте .toString () для замены в функции _utf8_encode, потому что если передана строка json, она вызовет исключение
Не работает с юникодом. Сделайте: Base64.encode ("?"), а затем расшифруйте его здесь: base64decode.org
Вы можете использовать btoa() и atob() для преобразования в кодировку base64 и обратно.
Похоже, что в комментариях есть некоторая путаница относительно того, что эти функции принимают / возвращают, поэтому ...
btoa() принимает «строку», где каждый символ представляет 8-битный байт - если вы передаете строку, содержащую символы, которые не могут быть представлены в 8-битном формате, это, вероятно, сломается. Это не проблема. если вы на самом деле обрабатываете строку как байтовый массив, но если вы пытаетесь сделать что-то еще, вам придется сначала ее закодировать.
atob() возвращает «строку», в которой каждый символ представляет 8-битный байт, то есть его значение будет между 0 и 0xff. Это означает, что нет означает, что это ASCII - предположительно, если вы вообще используете эту функцию, вы ожидаете работать с двоичными данными, а не с текстом.
Большинство комментариев здесь устарели. Вероятно, вы можете использовать и btoa(), и atob(), если только вы не поддерживаете действительно устаревшие браузеры.
Проверить здесь:
Обратите внимание, что это также работает для браузеров webkit, таких как Safari.
Обратите внимание на особое внимание к строкам Unicode: developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa и atob правильно работают только для строк на основе ASCII. Как американец, вы, вероятно, не заметите разницы ... но при первом использовании символа с диакритическими знаками ваш код сломается.
вы должны использовать btoa(unescape(encodeURIComponent(str)))), если str - UFT8
Если эти функции поддерживают только строки ascii, их вообще не следует использовать. Период. Вы кодируете 64 байтовые массивы, а не символьные массивы (т.е. строки). Строки - это массивы логических символов, а не массивы байтов. Массивы символов необходимо сначала преобразовать в массивы байтов, выбрав кодировку символов (UTF8, UTF16 или UTF32), чтобы преобразовать каждый символ в последовательности из одного или нескольких байтов (для схем кодирования с переменной длиной, таких как UTF8 или UFT16) или последовательностей. фиксированной длины (в схемах кодирования постоянной длины, таких как UTF32). Как только у вас есть байтовый массив, закодируйте его в base64.
Смотрите мою редакцию, @Triynko. Они не предназначены для использования для обработки текст, период.
Хорошо, меня сбило с толку комментарий Дэна о том, что btoa и atob правильно работают только для строк ASCII. Эти функции на самом деле вообще не предназначены для работы с фактическими символьными строками, а скорее с байтовыми массивами, которые хранятся в строках, так что для каждого символа в строке вызов charCodeAt (i) всегда будет возвращать значение между 0 и 255. Я видел это раньше в классе JavaScript Base64, который сначала кодировал бы строку utf8 в другую строку (точно так, как описано, где каждый «символ» фактически представляет значение байта), а затем кодирует это значение в базе 64.
Таким образом, еще более эффективным методом было бы использовать что-то вроде этого (webtoolkit.info/javascript-base64.html) и просто кодировать через: var encoded = btoa(Base64._utf8_encode(input)) и декодировать с помощью var decoded = Base64._utf8_decode(atob(encoded)). Мне кажется, что выполнение кодировки utf8 гораздо менее подвержено ошибкам, чем передача ввода через unescape(encodeURIComponent(str)). Кроме того, строку string = string.replace(/\r\n/g,"\n"); следует удалить из функции _utf8_encode, поскольку такая нормализация разрыва строки не имеет отношения к базовой функции кодирования utf8.
Вот полифилл github.com/davidchambers/Base64.js, лучше использовать собственные функции и полифил, а не включать библиотеку, которая представляет новый API.
И обратное к base64-декодированию строки UTF8, закодированной методом SET: decodeURIComponent (escape (window.atob (b64)));
Для того, кто предложил это редактирование: действительно не могу достаточно подчеркнуть, что вы не должны передавать произвольные строки в btoa(). Да, этот пример подойдет ... Но он вводит в заблуждение; широкие символы (допустимые в строковом литерале) могут вызвать проблемы.
Для лучшего запоминания названий функций: btoa() - это бб>efore каfter, atob() - аfter к бб>efore
Javascript - такой пьяный язык. atob, по-видимому, означает «буквенно-цифровой код в base64», поэтому конечно фактически делает наоборот.
двоичный, @Will. Буква b означает «двоичный». Как те отрывочные телеконференции.
да, но ... Он используется для преобразования строк в base64 ... любой непьющий кодер назвал бы его toBase64, поддерживал бы юникод, а потом вышел бы выпить.
Итак, вот где люди продолжают путаться здесь, @Will - абсолютно необходимо использовать нет для преобразования строк во что-либо или из чего-либо, если только они не являются строками Base64 (a.k.a, alt.binaries -> "b"). Как видите, кодеры были не пьяны, а извращенцы.
Он произносится как b to a и a to b, где b означает двоичный файл, а знак ASCII.
Ввод / вывод "a" должен быть допустимым ASCII, так как это обычное намерение Base64 @Captain. Ни при каких обстоятельствах не предполагайте, что вывод «b» действителен в любой кодировке текста, и не отправляйте текст, который не умещается в 8-битном формате, в функцию, ожидающую «b».
@ Shog9 Как jpp предложенный, я хотел бы представить вашему вниманию свой мета вопрос и соответствующий редактировать ответа Санни Миленова. Я надеюсь, что такое обращение к вам приемлемо.
Я постараюсь найти время, чтобы взглянуть на это, @TS, но имейте в виду, что многие ответы здесь делают дополнительные вещи, потому что, в отличие от исходного вопроса, они пытаются передать Unicode струны через системы, которые не не поддерживает Unicode ... И использует кодировку Base64 как часть этого процесса. Хотя это, безусловно, понятно, иногда возникают некоторые противоречивые (и ... плохо определенные) требования.
Код Санни великолепен, за исключением того, что он ломается в IE7 из-за ссылок на «this». Исправлено заменой таких ссылок на "Base64":
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");
while (i < input.length) {
enc1 = Base64._keyStr.indexOf(input.charAt(i++));
enc2 = Base64._keyStr.indexOf(input.charAt(i++));
enc3 = Base64._keyStr.indexOf(input.charAt(i++));
enc4 = Base64._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
о, моя беда, я получал ввод из URL-адреса браузера; где | конвертируется в% 7C; следовательно, кодировка тоже неправильная.
Я знаю, что это действительно устарело, но я видел, что эта функция использовалась более чем в одном месте, строка ключа на самом деле состоит из 65 символов, а не 64. Строка не является стандартной спецификацией, я не уверен, что это имеет значение, но просто интересно если это так?
"использовать строго"; это то, что ломает «this» и другие элементы типа, такие как «with», и, судя по тому, что я прочитал, «eval» подвергается критике. Все неуместные идеи о злоупотреблениях. Лично я не понимаю, почему JavaScript должен идти по пути своего продвижения, он никогда не задумывался как программа, сильно связанная и усложненная, чем она есть. Если вы хотите, чтобы вас связали, создайте компилятор для javascript.
Я пытаюсь использовать эту функцию и получаю сообщение об ошибке: Причина: org.mozilla.javascript.EcmaError: TypeError: Не удается найти замену функции в объекте teste teste teste Я пытаюсь закодировать .txt с помощью «teste teste teste». Кто-нибудь знает, почему эта ошибка?
@JonathanWagner - для нормальной кодировки используется 64 символа. 65-й символ используется в качестве дополнения к ним, входная строка не имеет количества символов, делящихся на 3.
В обеих реализациях _utf8_decode есть пара ошибок. c1 и c2 назначаются как глобальные переменные из-за неправильного использования оператора var, а c3 не инициализируется и не объявляется вообще.
Это работает, но эти переменные перезапишут любые существующие переменные с тем же именем вне этой функции.
Вот версия, которая этого не сделает:
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = 0, c1 = 0, c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if ((c > 191) && (c < 224)) {
c1 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
i += 2;
}
else {
c1 = utftext.charCodeAt(i+1);
c2 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
i += 3;
}
}
return string;
}
@Daan У меня не было достаточно репутации, чтобы редактировать ответы, когда я писал этот ответ ... в 2011 году.
IE7? Я думаю, нам следует перестать тратить время на написание кода для этого, люди не перестанут использовать эту старую технологию, если мы, разработчики, их не заставим!
@RonanDejhero не работает в IE7? Я не помню, тестировал ли я в этом конкретном браузере.
Я имел в виду, что если он не работает в IE7, никого не волнует !. я не тестировал и тестировать не буду :)
Чтобы сделать строковый URL-адрес в кодировке Base64 дружественным, в JavaScript вы можете сделать что-то вроде этого:
// if this is your Base64 encoded string
var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA==';
// make URL friendly:
str = str.replace(/\+/g, '-').replace(///g, '_').replace(/\=+$/, '');
// reverse to original encoding
str = (str + '===').slice(0, str.length + (str.length % 4));
str = str.replace(/-/g, '+').replace(/_/g, '/');
См. Также эту скрипку: http://jsfiddle.net/magikMaker/7bjaT/
Я бы смиренно предположил, что использование encodeURIComponent вполне может привести к превосходному результату с меньшими затратами усилий со стороны разработчика.
encodeURIComponent изменит длину строк в кодировке base64, а замена '-' и '_' на '+' и '/' является стандартной практикой при использовании base64 в URL-адресах (например, docs.python.org/library/base64.html#base64.urlsafe_b64encode). Не нужно расстраиваться.
Вы можете использовать btoa (до base-64) и atob (от base-64).
Для IE 9 и ниже попробуйте плагин jquery-base64:
$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q = ");
Почему все должно быть плагином jQuery: c это всего лишь основная функциональность JavaScript, не имеющая ничего общего с DOM или jQuery
Это не основная функциональность, иначе было бы не так много разных ответов с высокими оценками (включая самодельный код tl; dr). Итак, imho, на самом деле это хороший вариант использования jQuery (один лайнер, ожидается, что он будет работать даже в Android WebView) - даже больше, если он уже является зависимостью.
Я ушел и сдался. Подмножество jQuery следует формализовать и ввести в стандарт JS как «.net». Это некрасиво, но потребность огромна, и она пришла, чтобы управлять экосистемой.
Мне нравится устанавливать такие фрагменты кода в jQuery главным образом потому, что они будут существовать в контролируемом пространстве имен. Если вы не используете AMD, CommonJS или аналогичный шаблон проектирования, ваше глобальное пространство имен может легко запутаться из-за кучи случайных функций.
Это «глобальное пространство имен», и использование фреймворков для выполнения небольших программ, идея пакета и JQuery написаны на JavaScript, ЭТО НЕ ЯВЛЯЕТСЯ JavaScript. Прочтите об atob () и btoa (), потому что вы обнаружите, что они не согласованы между типами браузеров.
@Risadinha - за исключением того, что его функциональность не зависит от чего-либо jQuery и не расширяет его ... буквально единственные ссылки на jQuery в его коде прикрепляют его к объекту jQuery ... так какой смысл прикреплять его к jQuery и, следовательно, требовать jQuery использовать? Просто сделайте его собственным 1 вкладышем base64.encode(...) и base64.decode(...) ... прикреплять его к jQuery, когда он не имеет никакой специфической функциональности jQuery, не имеет абсолютно никакого смысла ...
jQuery не запрашивался. Не верный ответ на простой старый вопрос JS.
Я добавил +1 к ответу Санни, но я хотел внести несколько изменений, которые я внес в свой собственный проект, на случай, если кто-то сочтет это полезным. По сути, я только что немного очистил исходный код, чтобы JSLint не жаловался так сильно, и я сделал методы, отмеченные как частные в комментариях, на самом деле частными. Я также добавил два метода, которые мне понадобились в моем собственном проекте, а именно decodeToHex и encodeFromHex.
Код:
var Base64 = (function() {
"use strict";
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ";
var _utf8_encode = function (string) {
var utftext = "", c, n;
string = string.replace(/\r\n/g,"\n");
for (n = 0; n < string.length; n++) {
c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
};
var _utf8_decode = function (utftext) {
var string = "", i = 0, c = 0, c1 = 0, c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c1 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
i += 2;
} else {
c1 = utftext.charCodeAt(i+1);
c2 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
i += 3;
}
}
return string;
};
var _hexEncode = function(input) {
var output = '', i;
for(i = 0; i < input.length; i++) {
output += input.charCodeAt(i).toString(16);
}
return output;
};
var _hexDecode = function(input) {
var output = '', i;
if (input.length % 2 > 0) {
input = '0' + input;
}
for(i = 0; i < input.length; i = i + 2) {
output += String.fromCharCode(parseInt(input.charAt(i) + input.charAt(i + 1), 16));
}
return output;
};
var encode = function (input) {
var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output += _keyStr.charAt(enc1);
output += _keyStr.charAt(enc2);
output += _keyStr.charAt(enc3);
output += _keyStr.charAt(enc4);
}
return output;
};
var decode = function (input) {
var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output += String.fromCharCode(chr1);
if (enc3 !== 64) {
output += String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output += String.fromCharCode(chr3);
}
}
return _utf8_decode(output);
};
var decodeToHex = function(input) {
return _hexEncode(decode(input));
};
var encodeFromHex = function(input) {
return encode(_hexDecode(input));
};
return {
'encode': encode,
'decode': decode,
'decodeToHex': decodeToHex,
'encodeFromHex': encodeFromHex
};
}());
Сначала я думал, что развертывание выходной конкатенации в отдельные операторы будет более оптимальным, но после того, как я подумал об этом на секунду, этот должен будет более неэффективным, поскольку строки Javascript неизменны, и при работе это вызовет 4 копии потенциально огромных больших двоичных объектов с большими двоичными файлами данных. Более безопасный вариант - сначала объединить 4 символа вместе, а затем построить новую строку. Хотел бы я знать наверняка о лучшем методе построения струн, который был бы эффективен на всех платформах. (даже IE6)
Я не рассматривал производительность при очистке первоначально опубликованного кода. Я просто сделал его более читабельным и сделал методы, отмеченные как частные в комментариях в оригинале, на самом деле частными, используя шаблон модуля раскрытия. Я уверен, что его можно оптимизировать и с точки зрения производительности. Не совсем уверен, когда здесь начнется сборка мусора, а хеширование больших файлов с помощью Javascript не очень распространено (или, скорее всего, не является оптимальным решением в любом случае).
Забавно, как здесь живет этот код. На этой странице уже есть 3 разные версии.
если вам нужно закодировать объект изображения HTML, вы можете написать простую функцию, например:
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
// escape data:image prefix
return dataURL.replace(/^data:image/(png|jpg);base64,/, "");
// or just return dataURL
// return dataURL
}
Чтобы получить base64 изображения по идентификатору:
function getBase64ImageById(id){
return getBase64Image(document.getElementById(id));
}
узнать больше здесь
Ага, и var img = new Image (); img.src = "../images/myPic.png";
Обратите внимание, что это не подходит для необработанных строк Unicode! См. Раздел Unicode здесь.
Синтаксис для кодирования
var encodedData = window.btoa(stringToEncode);
Синтаксис для декодирования
var decodedData = window.atob(encodedData);
Прямая ссылка на раздел юникода: developer.mozilla.org/en-US/docs/Web/API/…
Я вручную переписал эти методы кодирования и декодирования, за исключением шестнадцатеричного, в модульный формат для кросс-платформенной / браузерной совместимости, а также с реальной частной областью видимости, и использует btoa и atob, если они существуют, скорее из-за скорости чем использовать собственную кодировку:
https://gist.github.com/Nijikokun/5192472
Использование:
base64.encode(/* String */);
base64.decode(/* String */);
utf8.encode(/* String */);
utf8.decode(/* String */);
В моем проекте мне все еще нужно поддерживать IE7 и работать с большими входными данными для кодирования.
На основе кода, предложенного Джо Диндейлом и предложенного в комментарии Мариуса, можно улучшить производительность с IE7, построив результат с помощью массива вместо строки.
Вот пример кодирования:
var encode = function (input) {
var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output.push(_keyStr.charAt(enc1));
output.push(_keyStr.charAt(enc2));
output.push(_keyStr.charAt(enc3));
output.push(_keyStr.charAt(enc4));
}
return output.join("");
};
Что ж, если вы используете додзё, это дает нам прямой способ кодирования или декодирования в base64.
Попробуй это:-
Чтобы закодировать массив байтов с помощью dojox.encoding.base64:
var str = dojox.encoding.base64.encode(myByteArray);
Чтобы декодировать строку в кодировке base64:
var bytes = dojox.encoding.base64.decode(str);
Я бы предпочел использовать методы кодирования / декодирования bas64 из CryptoJS, самой популярной библиотеки для стандартных и безопасных криптографических алгоритмов, реализованных на JavaScript с использованием лучших практик и шаблонов.
Внесение вклада в минифицированный полифилл для window.atob + window.btoa, который я сейчас использую.
(function(){function t(t){this.message=t}var e = "undefined"!=typeof exports?exports:this,r = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ";t.prototype=Error(),t.prototype.name = "InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c = "";e.charAt(0|a)||(i = " = ",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if (n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if (e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c = "";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
Вот версия @ user850789 для AngularJS Factory:
'use strict';
var ProjectNameBase64Factory = angular.module('project_name.factories.base64', []);
ProjectNameBase64Factory.factory('Base64', function () {
var Base64 = {
// private property
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",
// public method for encoding
encode: function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode: function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");
while (i < input.length) {
enc1 = Base64._keyStr.indexOf(input.charAt(i++));
enc2 = Base64._keyStr.indexOf(input.charAt(i++));
enc3 = Base64._keyStr.indexOf(input.charAt(i++));
enc4 = Base64._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode: function (string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode: function (utftext) {
var string = "";
var i = 0;
var c = 0, c2 = 0, c3 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
};
return Base64;
});
Мне нужна была кодировка строки UTF-8 как base64 для моего проекта. Большинство ответов здесь, похоже, неправильно обрабатывают суррогатные пары UTF-16 при преобразовании в UTF-8, поэтому для завершения я опубликую свое решение:
function strToUTF8Base64(str) {
function decodeSurrogatePair(hi, lo) {
var resultChar = 0x010000;
resultChar += lo - 0xDC00;
resultChar += (hi - 0xD800) << 10;
return resultChar;
}
var bytes = [0, 0, 0];
var byteIndex = 0;
var result = [];
function output(s) {
result.push(s);
}
function emitBase64() {
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz' +
'0123456789+/';
function toDigit(value) {
return digits[value];
}
// --Byte 0-- --Byte 1-- --Byte 2--
// 1111 1122 2222 3333 3344 4444
var d1 = toDigit(bytes[0] >> 2);
var d2 = toDigit(
((bytes[0] & 0x03) << 4) |
(bytes[1] >> 4));
var d3 = toDigit(
((bytes[1] & 0x0F) << 2) |
(bytes[2] >> 6));
var d4 = toDigit(
bytes[2] & 0x3F);
if (byteIndex === 1) {
output(d1 + d2 + '==');
}
else if (byteIndex === 2) {
output(d1 + d2 + d3 + '=');
}
else {
output(d1 + d2 + d3 + d4);
}
}
function emit(chr) {
bytes[byteIndex++] = chr;
if (byteIndex == 3) {
emitBase64();
bytes[0] = 0;
bytes[1] = 0;
bytes[2] = 0;
byteIndex = 0;
}
}
function emitLast() {
if (byteIndex > 0) {
emitBase64();
}
}
// Converts the string to UTF8:
var i, chr;
var hi, lo;
for (i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
// Test and decode surrogate pairs in the string
if (chr >= 0xD800 && chr <= 0xDBFF) {
hi = chr;
lo = str.charCodeAt(i + 1);
if (lo >= 0xDC00 && lo <= 0xDFFF) {
chr = decodeSurrogatePair(hi, lo);
i++;
}
}
// Encode the character as UTF-8.
if (chr < 0x80) {
emit(chr);
}
else if (chr < 0x0800) {
emit((chr >> 6) | 0xC0);
emit(((chr >> 0) & 0x3F) | 0x80);
}
else if (chr < 0x10000) {
emit((chr >> 12) | 0xE0);
emit(((chr >> 6) & 0x3F) | 0x80);
emit(((chr >> 0) & 0x3F) | 0x80);
}
else if (chr < 0x110000) {
emit((chr >> 18) | 0xF0);
emit(((chr >> 12) & 0x3F) | 0x80);
emit(((chr >> 6) & 0x3F) | 0x80);
emit(((chr >> 0) & 0x3F) | 0x80);
}
}
emitLast();
return result.join('');
}
Обратите внимание, что код не прошел тщательную проверку. Я протестировал некоторые входные данные, включая такие вещи, как strToUTF8Base64('衠衢蠩蠨'), и сравнил их с выходными данными онлайн-инструмента кодирования (https://www.base64encode.org/).
// Define the string
var string = 'Hello World!';
// Encode the String
var encodedString = btoa(string);
console.info(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
// Decode the String
var decodedString = atob(encodedString);
console.info(decodedString); // Outputs: "Hello World!"
// Create Base64 Object
var Base64 = {_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",encode:function(e){var t = "";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if (isNaN(r)){u=a=64}else if (isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t = "";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if (u!=64){t=t+String.fromCharCode(r)}if (a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t = "";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if (r<128){t+=String.fromCharCode(r)}else if (r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t = "";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if (r<128){t+=String.fromCharCode(r);n++}else if (r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
// Define the string
var string = 'Hello World!';
// Encode the String
var encodedString = Base64.encode(string);
console.info(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
// Decode the String
var decodedString = Base64.decode(encodedString);
console.info(decodedString); // Outputs: "Hello World!"
Вот как вы кодируете обычный текст в base64 в Node.js:
//Buffer() requires a number, array or string as the first parameter, and an optional encoding type as the second parameter.
// Default is utf8, possible encoding types are ascii, utf8, ucs2, base64, binary, and hex
var b = new Buffer('JavaScript');
// If we don't use toString(), JavaScript assumes we want to convert the object to utf8.
// We can make it convert to other formats by passing the encoding type to toString().
var s = b.toString('base64');
А вот как вы декодируете строки в кодировке base64:
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();
Чтобы закодировать массив байтов с помощью dojox.encoding.base64:
var str = dojox.encoding.base64.encode(myByteArray);
Чтобы декодировать строку в кодировке base64:
var bytes = dojox.encoding.base64.decode(str)
<script src = "bower_components/angular-base64/angular-base64.js"></script>
angular
.module('myApp', ['base64'])
.controller('myController', [
'$base64', '$scope',
function($base64, $scope) {
$scope.encoded = $base64.encode('a string');
$scope.decoded = $base64.decode('YSBzdHJpbmc=');
}]);
Этот ответ основан на исходном коде и НЕ включает обновления этого кода, опубликованные в других ответах здесь.
Предлагаемое решение NodeJS устарело.
new Buffer() устарел, используйте вместо него Buffer.from()Немного больше работы, но если вам нужно высокопроизводительное собственное решение, вы можете использовать некоторые функции HTML5.
Если вы можете поместить свои данные в Blob, то вы можете использовать функцию FileReader.readAsDataURL (), чтобы получить URL-адрес data://, и отрезать его переднюю часть, чтобы получить данные base64.
Возможно, вам придется выполнить дополнительную обработку, чтобы url-декодировать данные, поскольку я не уверен, экранируются ли символы + или нет для URL-адреса data://, но это должно быть довольно тривиально.
Этот вопрос и ответы на него указали мне правильное направление. Особенно с unicode atob и btoa нельзя использовать "vanilla", и в наши дни ВСЕ - unicode ..
Непосредственно из Mozilla, две приятные функции для этой цели (протестированы с помощью тегов unicode и html внутри)
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU = "
b64EncodeUnicode('\n'); // "Cg= = "
function b64DecodeUnicode(str) {
return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
b64DecodeUnicode('Cg=='); // "\n"
Эти функции будут выполнять молниеносную работу по сравнению с необработанным декодированием base64 с использованием пользовательской функции javascript, поскольку btoa и atob выполняются вне интерпретатора.
Если вы можете игнорировать старый IE и старые мобильные телефоны (например, iphone 3?), Это должно быть хорошим решением.
Это из MDN?
Из комментариев (SET и Stefan Steiger) ниже принятого ответа, вот краткое изложение того, как кодировать / декодировать строку в / из base64 без необходимости в библиотеке.
str = "The quick brown fox jumps over the lazy dog";
b64 = btoa(unescape(encodeURIComponent(str)));
str = decodeURIComponent(escape(window.atob(b64)));
(использует библиотеку jQuery, но не для кодирования / декодирования)
str = "The quick brown fox jumps over the lazy dog";
$('input').val(str);
$('#btnConv').click(function(){
var txt = $('input').val();
var b64 = btoa(unescape(encodeURIComponent(txt)));
$('input').val(b64);
$('#btnDeConv').show();
});
$('#btnDeConv').click(function(){
var b64 = $('input').val();
var txt = decodeURIComponent(escape(window.atob(b64)));
$('input').val(txt);
});#btnDeConv{display:none;}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type = "text" />
<button id = "btnConv">Convert</button>
<button id = "btnDeConv">DeConvert</button>Подтверждаю, что это поддерживает символы UTF-8?
@Crashalot Я понимаю, что это на два года слишком поздно, но да, это так. Когда я набираю это, я также просто понимаю, что вы предоставили правку, которая, возможно, заставила UTF8 работать.
Для всех, кто здесь ищет хорошее решение для использования с Node.js, я могу подтвердить, что это работает. Для декодирования в Node я использовал: Buffer.from(b64data, 'base64').toString();
Может кто-нибудь объяснить, что делают unescape и escape в этом снятом решении?
Вы можете использовать window.btoa и window.atob ...
const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
const decoded = window.atob(encoded); // decode the string
Вероятно, использование способа, которым является MDN, может сделать вашу работу лучше всего ... Также принятие Unicode ... с использованием этих двух простых функций:
// ucs-2 string to base64 encoded ascii
function utoa(str) {
return window.btoa(unescape(encodeURIComponent(str)));
}
// base64 encoded ascii to ucs-2 string
function atou(str) {
return decodeURIComponent(escape(window.atob(str)));
}
// Usage:
utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
Чтобы новые браузеры кодировали Uint8Array в строку и декодировали строку в Uint8Array.
const base64 = {
decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
encode: b => btoa(String.fromCharCode(...new Uint8Array(b)))
};
Для Node.js вы можете использовать следующее для кодирования строки, Buffer или Uint8Array в строку и декодирования из строки, Buffer или Uint8Array в Buffer.
const base64 = {
decode: s => Buffer.from(s, 'base64'),
encode: b => Buffer.from(b).toString('base64')
};
не хорошо. ошибочный.
Вот ЖИВАЯ ДЕМО встроенных функций atob() и btoa() JS:
<!DOCTYPE html>
<html>
<head>
<style>
textarea{
width:30%;
height:100px;
}
</style>
<script>
// encode string to base64
function encode()
{
var txt = document.getElementById("txt1").value;
var result = btoa(txt);
document.getElementById("txt2").value = result;
}
// decode base64 back to original string
function decode()
{
var txt = document.getElementById("txt3").value;
var result = atob(txt);
document.getElementById("txt4").value = result;
}
</script>
</head>
<body>
<div>
<textarea id = "txt1">Some text to decode
</textarea>
</div>
<div>
<input type = "button" id = "btnencode" value = "Encode" onClick = "encode()"/>
</div>
<div>
<textarea id = "txt2">
</textarea>
</div>
<br/>
<div>
<textarea id = "txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
</textarea>
</div>
<div>
<input type = "button" id = "btndecode" value = "Decode" onClick = "decode()"/>
</div>
<div>
<textarea id = "txt4">
</textarea>
</div>
</body>
</html>
Использовать библиотеку js-base64 как
btoa() doesn't work with emojis
var str = "I was funny ?";
console.info("Original string:", str);
var encodedStr = Base64.encode(str)
console.info("Encoded string:", encodedStr);
var decodedStr = Base64.decode(encodedStr)
console.info("Decoded string:", decodedStr);<script src = "https://cdn.jsdelivr.net/npm/[email protected]/base64.min.js"></script>Вы можете использовать btoa () / atob () в браузере, но требуются некоторые улучшения, как описано здесь: https://base64tool.com/uncaught-domexception-btoa-on-window/ и https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa для поддержки строк UTF!
btoa (без библиотеки)В заголовке вопроса вы пишете о преобразовании строк, но в вопросе вы говорите о двоичных данных (изображение), поэтому вот функция, которая выполняет правильное преобразование, начиная с двоичных данных изображения PNG (подробности и обратное преобразование здесь)
function bytesArrToBase64(arr) {
const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 alphabet
const bin = n => n.toString(2).padStart(8,0); // convert num to 8-bit binary string
const l = arr.length
let result = '';
for(let i=0; i<=(l-1)/3; i++) {
let c1 = i*3+1>=l; // case when " = " is on end
let c2 = i*3+2>=l; // case when " = " is on end
let chunk = bin(arr[3*i]) + bin(c1? 0:arr[3*i+1]) + bin(c2? 0:arr[3*i+2]);
let r = chunk.match(/.{1,6}/g).map((x,j)=> j==3&&c2 ? '=' :(j==2&&c1 ? '=':abc[+('0b'+x)]));
result += r.join('');
}
return result;
}
// TEST
const pic = [ // PNG binary data
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00,
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f,
0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65,
0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22,
0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74,
0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d,
0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e,
0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64,
0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a,
0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31,
0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64,
0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23,
0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64,
0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d,
0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66,
0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73,
0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74,
0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66,
0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72,
0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a,
0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46,
0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74,
0x61, 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x00, 0xf9, 0x49,
0x44, 0x41, 0x54, 0x38, 0x11, 0x95, 0x93, 0x3d, 0x0a, 0x02, 0x41, 0x0c,
0x85, 0xb3, 0xb2, 0x85, 0xb7, 0x10, 0x6c, 0x04, 0x1b, 0x0b, 0x4b, 0x6f,
0xe2, 0x76, 0x1e, 0xc1, 0xc2, 0x56, 0x6c, 0x2d, 0xbc, 0x85, 0xde, 0xc4,
0xd2, 0x56, 0xb0, 0x11, 0xbc, 0x85, 0x85, 0xa0, 0xfb, 0x46, 0xbf, 0xd9,
0x30, 0x33, 0x88, 0x06, 0x76, 0x93, 0x79, 0x93, 0xf7, 0x92, 0xf9, 0xab,
0xcc, 0xec, 0xd9, 0x7e, 0x7f, 0xd9, 0x63, 0x33, 0x8e, 0xf9, 0x75, 0x8c,
0x92, 0xe0, 0x34, 0xe8, 0x27, 0x88, 0xd9, 0xf4, 0x76, 0xcf, 0xb0, 0xaa,
0x45, 0xb2, 0x0e, 0x4a, 0xe4, 0x94, 0x39, 0x59, 0x0c, 0x03, 0x54, 0x14,
0x58, 0xce, 0xbb, 0xea, 0xdb, 0xd1, 0x3b, 0x71, 0x75, 0xb9, 0x9a, 0xe2,
0x7a, 0x7d, 0x36, 0x3f, 0xdf, 0x4b, 0x95, 0x35, 0x09, 0x09, 0xef, 0x73,
0xfc, 0xfa, 0x85, 0x67, 0x02, 0x3e, 0x59, 0x55, 0x31, 0x89, 0x31, 0x56,
0x8c, 0x78, 0xb6, 0x04, 0xda, 0x23, 0x01, 0x01, 0xc8, 0x8c, 0xe5, 0x77,
0x87, 0xbb, 0x65, 0x02, 0x24, 0xa4, 0xad, 0x82, 0xcb, 0x4b, 0x4c, 0x64,
0x59, 0x14, 0xa0, 0x72, 0x40, 0x3f, 0xbf, 0xe6, 0x68, 0xb6, 0x9f, 0x75,
0x08, 0x63, 0xc8, 0x9a, 0x09, 0x02, 0x25, 0x32, 0x34, 0x48, 0x7e, 0xcc,
0x7d, 0x10, 0xaf, 0xa6, 0xd5, 0xd2, 0x1a, 0x3d, 0x89, 0x38, 0xf5, 0xf1,
0x14, 0xb4, 0x69, 0x6a, 0x4d, 0x15, 0xf5, 0xc9, 0xf0, 0x5c, 0x1a, 0x61,
0x8a, 0x75, 0xd1, 0xe8, 0x3a, 0x2c, 0x41, 0x5d, 0x70, 0x41, 0x20, 0x29,
0xf9, 0x9b, 0xb1, 0x37, 0xc5, 0x4d, 0xfc, 0x45, 0x84, 0x7d, 0x08, 0x8f,
0x89, 0x76, 0x54, 0xf1, 0x1b, 0x19, 0x92, 0xef, 0x2c, 0xbe, 0x46, 0x8e,
0xa6, 0x49, 0x5e, 0x61, 0x89, 0xe4, 0x05, 0x5e, 0x4e, 0xa4, 0x5c, 0x10,
0x6e, 0x9f, 0xfc, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
0xae, 0x42, 0x60, 0x82
];
let b64pic = bytesArrToBase64(pic);
myPic.src = "data:image/png;base64,"+b64pic;
msg.innerHTML = "Base64 encoded pic data:<br>" + b64pic;img { zoom: 10; image-rendering: pixelated; }
#msg { word-break: break-all; }<img id = "myPic">
<code id = "msg"></code>let a = Buffer.from('JavaScript').toString('base64');
console.info(a);
let b = Buffer.from(a, 'base64').toString();
console.info(b);
вот другой плагин jquery для кодирования / декодирования base64