Кодирование и декодирование Base64 в Javascript на стороне клиента - PullRequest
225 голосов
/ 12 мая 2010

Есть ли в JavaScript какие-либо методы, которые можно использовать для кодирования и декодирования строки с использованием кодировки base64?

Ответы [ 11 ]

177 голосов
/ 12 мая 2010

Некоторые браузеры, такие как Firefox, Chrome, Safari, Opera и IE10 +, могут работать с Base64 изначально. Взгляните на этот вопрос Stackoverflow . Он использует функции btoa() и atob() .

Для серверного JavaScript есть пакет btoa для Node.JS .

Если вы собираетесь использовать кросс-браузерное решение, существуют существующие библиотеки, такие как CryptoJS или код:

http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

В последнем случае вам необходимо тщательно протестировать функцию на совместимость с различными браузерами. И об ошибке уже сообщалось .

62 голосов
/ 15 января 2011

В браузерах на основе Gecko / WebKit (Firefox, Chrome и Safari) и Opera вы можете использовать btoa () и atob () .

Оригинальный ответ: Как можно кодировать строку в Base64 в JavaScript?

47 голосов
/ 15 сентября 2014

Internet Explorer 10 +

// Define the string
var string = 'Hello World!';

// Encode the String
var encodedString = btoa(string);
console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

// Decode the String
var decodedString = atob(encodedString);
console.log(decodedString); // Outputs: "Hello World!"

Cross-Browser

Переписанные и модульные библиотеки / модули кодирования и декодирования JavaScript UTF-8 и Base64 для AMD, CommonJS, Nodejs и браузеров. Кросс-браузер совместим.


с Node.js

Вот как вы кодируете обычный текст в 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();

с Dojo.js

Для кодирования массива байтов с использованием dojox.encoding.base64:

var str = dojox.encoding.base64.encode(myByteArray);

Для декодирования строки в кодировке base64:

var bytes = dojox.encoding.base64.decode(str)

Bower установить angular-base64

<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=');
}]);

а как?

Если вы хотите узнать больше о том, как base64 кодируется в целом, и, в частности, в JavaScript, я рекомендую эту статью: Информатика в JavaScript: кодировка Base64

39 голосов
/ 22 февраля 2013

Вот сжатая версия сообщения Снайпера. Предполагается, что правильно сформированная строка base64 без возврата каретки. В этой версии устранены несколько петель, добавлено исправление &0xff от Ярослава, устранены завершающие нули, а также немного кода для гольфа.

decodeBase64 = function(s) {
    var e={},i,b=0,c,x,l=0,a,r='',w=String.fromCharCode,L=s.length;
    var A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    for(i=0;i<64;i++){e[A.charAt(i)]=i;}
    for(x=0;x<L;x++){
        c=e[s.charAt(x)];b=(b<<6)+c;l+=6;
        while(l>=8){((a=(b>>>(l-=8))&0xff)||(x<(L-2)))&&(r+=w(a));}
    }
    return r;
};
30 голосов
/ 17 июня 2010

Короткая и быстрая функция декодирования JavaScript Base64 без Failsafe:

function decode_base64 (s)
{
    var e = {}, i, k, v = [], r = '', w = String.fromCharCode;
    var n = [[65, 91], [97, 123], [48, 58], [43, 44], [47, 48]];

    for (z in n)
    {
        for (i = n[z][0]; i < n[z][1]; i++)
        {
            v.push(w(i));
        }
    }
    for (i = 0; i < 64; i++)
    {
        e[v[i]] = i;
    }

    for (i = 0; i < s.length; i+=72)
    {
        var b = 0, c, x, l = 0, o = s.substring(i, i+72);
        for (x = 0; x < o.length; x++)
        {
            c = e[o.charAt(x)];
            b = (b << 6) + c;
            l += 6;
            while (l >= 8)
            {
                r += w((b >>> (l -= 8)) % 256);
            }
         }
    }
    return r;
}
11 голосов
/ 13 мая 2010

Проект php.js имеет реализации JavaScript многих функций PHP. base64_encode и base64_decode включены.

9 голосов
/ 14 апреля 2015

function b64_to_utf8( str ) {
  return decodeURIComponent(escape(window.atob( str )));
}

 https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22
8 голосов
/ 08 февраля 2014

Кто-то сказал код гольф? =) * * Тысяча одна

Следующее - моя попытка улучшить свой гандикап, не отставая от времени. Поставляется для вашего удобства.

function decode_base64(s) {
  var b=l=0, r='',
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  s.split('').forEach(function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
  });
  return r;
}

То, что я на самом деле преследовал, было асинхронной реализацией, и, к моему удивлению, получается forEach в отличие от реализации метода $([]).each в JQuery очень синхронно.

Если вы также имели в виду такие сумасшедшие представления, задержка 0 window.setTimeout запустит декодирование base64 асинхронно и выполнит функцию обратного вызова с результатом, когда это будет сделано.

function decode_base64_async(s, cb) {
  setTimeout(function () { cb(decode_base64(s)); }, 0);
}

@ Зубная щетка предложила «проиндексировать строку как массив» и избавиться от split. Эта процедура кажется действительно странной и не уверенной, насколько она будет совместимой, но она поражает другую птичку, так что давайте ее.

function decode_base64(s) {
  var b=l=0, r='',
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  [].forEach.call(s, function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
  });
  return r;
}

Пытаясь найти дополнительную информацию о строке JavaScript в виде массива, я наткнулся на этот профессиональный совет, используя регулярное выражение /./g для перехода по строке. Это еще больше уменьшает размер кода, заменяя строку на месте и избавляя от необходимости сохранять возвращаемую переменную.

function decode_base64(s) {
  var b=l=0,
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  return s.replace(/./g, function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    return l<8?'':String.fromCharCode((b>>>(l-=8))&0xff);
  });
}

Если, однако, вы искали что-то более традиционное, возможно, вам больше понравится.

function decode_base64(s) {
  var b=l=0, r='', s=s.split(''), i,
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  for (i in s) {
    b=(b<<6)+m.indexOf(s[i]); l+=6;
    if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
  }
  return r;
}

У меня не было завершающей нулевой проблемы, поэтому она была удалена, чтобы оставаться в соответствии с номиналом, но ее легко можно решить с помощью trim() или trimRight(), если вы предпочитаете, если это создаст проблему для вас.

т.

return r.trimRight();

Примечание:

В результате получается строка байтов ascii, если вам нужен юникод, проще всего escape строка байтов, которая затем может быть декодирована с помощью decodeURIComponent для получения строки юникода.

function decode_base64_usc(s) {      
  return decodeURIComponent(escape(decode_base64(s)));
}

Поскольку escape устарело, мы могли бы изменить нашу функцию для поддержки Юникода напрямую, без необходимости escape или String.fromCharCode, мы можем создать экранированную строку %, готовую для декодирования URI.

function decode_base64(s) {
  var b=l=0,
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  return decodeURIComponent(s.replace(/./g, function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    return l<8?'':'%'+(0x100+((b>>>(l-=8))&0xff)).toString(16).slice(-2);
  }));
}

NJoy!

6 голосов
/ 30 января 2013

Я пробовал подпрограммы Javascript на phpjs.org, и они хорошо работали.

Сначала я попробовал процедуры, предложенные в выбранном ответе Ранхиру Курей - http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

Я обнаружил, что они не работают при любых обстоятельствах. Я написал тестовый пример, где эти подпрограммы потерпели неудачу, и разместил их на GitHub по адресу:

https://github.com/scottcarter/base64_javascript_test_data.git

Я также разместил комментарий к сообщению в блоге на ntt.cc, чтобы предупредить автора (ожидает модерации - статья старая, поэтому не уверен, будет ли опубликован комментарий).

1 голос
/ 28 ноября 2017

В Node.js мы можем сделать это простым способом

var base64 = 'SGVsbG8gV29ybGQ='
var base64_decode = new Buffer(base64, 'base64').toString('ascii');

console.log(base64_decode); // "Hello World"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...