web-dev-qa-db-fra.com

Encodage et décodage Base64 en Javascript côté client

Existe-t-il des méthodes en JavaScript qui pourraient être utilisées pour encoder et décoder une chaîne en utilisant l’encodage base64?

214
Mo.

Certains navigateurs tels que Firefox, Chrome, Safari, Opera et IE10 + peuvent gérer Base64 de manière native. Jetez un oeil à cette question Stackoverflow question . Il utilise btoa() ET atob() .

Pour JavaScript côté serveur, il existe un paquet btoa pour Node.JS .

Si vous optez pour une solution multi-navigateurs, il existe des bibliothèques existantes telles que CryptoJS ou du code du type:

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

Dans ce dernier cas, vous devez tester minutieusement la fonction pour vérifier la compatibilité entre navigateurs. Et erreur a déjà été signalé .

171
Ranhiru Cooray

Dans les navigateurs basés sur Gecko/WebKit (Firefox, Chrome et Safari) et Opera, vous pouvez utiliser btoa () et atob () .

Réponse originale: Comment pouvez-vous encoder une chaîne en Base64 en JavaScript?

62
nyuszika7h

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!"

Navigateur croisé

Réécriture et modularisation de bibliothèques d'encodage et de décodage Javascript UTF-8 et Base64/Modules pour AMD, CommonJS, Nodejs et navigateurs. Compatible avec plusieurs navigateurs.


avec Node.js

Voici comment encoder du texte normal en base64 dans 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');

Et voici comment vous décodez des chaînes codées en base64:

var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();

avec Dojo.js

Pour coder un tableau d'octets à l'aide de dojox.encoding.base64:

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

Pour décoder une chaîne encodée en base64:

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

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

Mais comment?

Si vous souhaitez en savoir plus sur le codage de base64 en général et de JavaScript en particulier, je vous recommande cet article: Informatique en JavaScript: Encodage en Base64

42
davidcondrey

Voici une version plus précise du message de Sniper. Cela suppose une chaîne base64 bien formée sans retour à la ligne. Cette version élimine quelques boucles, ajoute le correctif &0xff de Yaroslav, élimine les valeurs NULL de fin et un peu de code golf.

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;
};
36
broc.seib

Fonction de décodage JavaScript Base64 courte et rapide sans sécurité intégrée:

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;
}
30
Sniper

Le projet php.js comporte des implémentations JavaScript de nombreuses fonctions de PHP. base64_encode et base64_decode sont inclus.

11
ceejayoz

Voici le meilleur moyen de base64_encode et base64_decode en utilisant javascript. Voir les liens ci-dessous.

http://phpjs.org/functions/base64_encode:358

http://phpjs.org/functions/base64_decode:357

10
gautamlakum

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
PPB

Quelqu'un a dit code golf? =)

Ce qui suit est ma tentative d’améliorer mon handicap tout en rattrapant mon temps. Fourni pour votre commodité.

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;
}

Ce que je recherchais en réalité, c’était une implémentation asynchrone et, à ma grande surprise, il s’avère que forEach, contrairement à la méthode $([]).each de JQuery, est très synchrone.

Si vous aviez aussi des notions aussi folles à l'esprit, un délai de 0 retard window.setTimeout exécutera le décodage en base64 de manière asynchrone et exécutera la fonction de rappel avec le résultat une fois terminé.

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

@Toothbrush a suggéré "d'indexer une chaîne comme un tableau" et de se débarrasser de split. Cette routine semble vraiment étrange et incertaine quant à sa compatibilité, mais elle frappe un autre oiseau alors laissons-la.

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;
}

Tout en essayant de trouver plus d'informations sur la chaîne JavaScript en tant que tableau, je suis tombé sur ce conseil professionnel en utilisant une regex /./g pour parcourir une chaîne. Cela réduit encore plus la taille du code en remplaçant la chaîne en place et en éliminant la nécessité de conserver une variable de retour.

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);
  });
}

Si toutefois vous recherchiez quelque chose d'un peu plus traditionnel, voici peut-être ce qui vous convient le mieux.

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;
}

Je n'avais pas le dernier problème, donc celui-ci a été supprimé, mais il devrait être facilement résolu avec un trim() ou un trimRight() si vous préférez, si cela vous pose problème.

c'est à dire.

return r.trimRight();

Remarque:

Le résultat est une chaîne d'octets ascii. Si vous avez besoin d'unicode, le plus simple est de escape la chaîne d'octets qui peut ensuite être décodée avec decodeURIComponent pour produire la chaîne unicode.

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

Puisque escape est obsolète, nous pourrions changer notre fonction pour prendre en charge unicode directement sans avoir besoin de escape ou String.fromCharCode, nous pouvons produire une chaîne échappée % prête pour le décodage 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);
  }));
}

nonJoy!

8
nickl-

J'ai essayé les routines Javascript sur phpjs.org et elles ont bien fonctionné.

J'ai d'abord essayé les routines suggérées dans la réponse choisie par Ranhiru Cooray - http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

J'ai trouvé qu'ils ne fonctionnaient pas dans toutes les circonstances. J'ai écrit un scénario de test où ces routines échouent et les ai postées sur GitHub à l'adresse:

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

J'ai également posté un commentaire sur le blog à l'adresse ntt.cc pour alerter l'auteur (en attente de modération - l'article est ancien, donc je ne sais pas si le commentaire sera publié).

6
Scott Carter

Je préférerais utiliser les méthodes d’encodage/décodage bas64 de CryptoJS , la bibliothèque la plus populaire pour les algorithmes de chiffrement standard et sécurisés implémentés en JavaScript et utilisant les meilleures pratiques et modèles.

1
Dan Dascalescu

Dans Node.js nous pouvons le faire de manière simple 

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

console.log(base64_decode); // "Hello World"
0
KARTHIKEYAN.A