1106 votes

Comment encoder une chaîne de caractères en Base64 en JavaScript ?

J'ai un script PHP qui peut encoder une image PNG en une chaîne Base64.

J'aimerais faire la même chose en utilisant JavaScript. Je sais comment ouvrir des fichiers, mais je ne suis pas sûr de savoir comment faire l'encodage. Je n'ai pas l'habitude de travailler avec des données binaires.

2 votes

Voici la meilleure façon de coder et décoder base64_encode et base64_decode en utilisant javascript. Voir les liens ci-dessous. phpjs.org/functions/base64_encode:358 phpjs.org/functions/base64_decode:357

0 votes

Voici un autre plugin jquery fo base64 encode/decode

0 votes

Vérifiez microjs : microjs.com/#base64

1216voto

Shog9 Points 82052

Vous pouvez utiliser btoa() et atob() pour convertir le codage base64.

Il semble y avoir une certaine confusion dans les commentaires concernant ce que ces fonctions acceptent/renvoient, donc

  • btoa() accepte une "chaîne" où chaque caractère représente un octet de 8 bits - si vous passez une chaîne contenant des caractères qui ne peuvent pas être représentés sur 8 bits, il se brisera probablement . Ce n'est pas un problème si vous traitez en fait la chaîne comme un tableau d'octets, mais si vous essayez de faire autre chose, vous devrez d'abord l'encoder.

  • atob() renvoie une "chaîne" où chaque caractère représente un octet de 8 bits - c'est-à-dire que sa valeur sera comprise entre 0 et 0xff . Cela ne pas signifie qu'il s'agit d'ASCII - si vous utilisez cette fonction, c'est que vous vous attendez à travailler avec des données binaires et non du texte.

Voir aussi :


La plupart des commentaires ici sont dépassés. Vous pouvez probablement utiliser les deux btoa() et atob() à moins que vous ne preniez en charge des navigateurs vraiment obsolètes.

Vérifiez ici :

50 votes

Notez que cela fonctionne également pour les navigateurs webkit, tels que Safari.

35 votes

Veuillez noter la considération spéciale pour les chaînes Unicode : developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa et atob ne fonctionnent correctement que pour les chaînes de caractères ASCII. En tant qu'Américain, vous ne remarquerez probablement pas de différence ... mais la première fois que vous utiliserez un caractère accentué, votre code sera cassé.

97 votes

Vous devez utiliser btoa(unescape(encodeURIComponent(str)))) si str est UFT8

314voto

Sunny Milenov Points 10978

D'ici :

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

}

Cherchez également sur "encodage javascript base64" tourne beaucoup d'autres options, celle ci-dessus a été la première.

3 votes

Ceci est également utile lorsque l'encodage base64 n'est pas standard ; dans mon cas, le caractère "/" n'a pas été utilisé, et le caractère " ?" a été utilisé à la place, ce qui signifie que même dans Chrome atob() n'allait pas décoder les chaînes base64 entrantes.

27 votes

Soyez prudent avec ce code - il tente d'interpréter votre chaîne comme une chaîne encodée en UTF-8. Nous avons eu un cas où nous avions une chaîne binaire (c'est-à-dire que chaque caractère de la chaîne doit être interprété comme un octet), et ce code a corrompu les données. Lisez la source, Luke.

2 votes

Si vous utilisez le code de webtoolkito info n'oubliez pas le copyright : /** * * Encodage / décodage Base64 * webtoolkit.info * **/

99voto

user850789 Points 741

Le code de Sunny est excellent, sauf qu'il ne fonctionne pas dans IE7 à cause des références à "this". Corrigé en remplaçant ces références par "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;
}
}

4 votes

Ooh ma faute, j'ai pris l'entrée de l'URL du navigateur ; où | est converti en %7C ; donc l'encodage est également faux.

0 votes

Je sais que c'est vraiment vieux, mais j'ai vu cette fonction utilisée à plusieurs endroits, la chaîne de clés est en fait à 65 caractères, pas 64. La chaîne n'est pas standard, je ne suis pas sûr que cela ait de l'importance, mais je me demandais juste si c'était le cas ?

0 votes

"use strict" ; c'est ce qui casse le "this" et d'autres éléments de type comme "with" et d'après ce que j'ai lu, "eval" est malmené. Toutes les idées déplacées sur l'abus. Personnellement, je ne vois pas pourquoi JavaScript doit prendre la route qu'il emprunte, il n'a jamais été conçu pour être un programme étroitement lié et rendu plus complexe qu'il ne l'est déjà. Si vous voulez être lié, alors faites un compilateur pour JavaScript.

94voto

Vitalii Fedorenko Points 17469

Vous pouvez utiliser btoa (en base-64) et atob (à partir de la base-64).

Pour IE 9 et les versions inférieures, essayez le jquery-base64 plugin :

$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");

147 votes

Pourquoi tout doit être un plugin jQuery :c c'est juste une fonctionnalité JavaScript de base qui n'a rien à voir avec le DOM ou jQuery.

40 votes

Il ne s'agit pas d'une fonctionnalité de base, sinon il n'y aurait pas autant de réponses différentes et votées (y compris du code "do-it-yourself tl;dr"). Donc, à mon avis, il s'agit d'un bon cas d'utilisation pour jQuery (une seule ligne, censée fonctionner même dans le WebView d'Android), d'autant plus s'il s'agit déjà d'une dépendance.

0 votes

Je suis parti et j'ai abandonné. Un sous-ensemble de jQuery devrait être formalisé et introduit dans la norme JS comme un ".net". Ce n'est pas très joli, mais le besoin est énorme et il est en train de régir l'écosystème.

27voto

robbles Points 1095

Il y a quelques bugs dans les deux implémentations de _utf8_decode . c1 et c2 sont assignées comme variables globales en raison de l'utilisation brisée de l'option var déclaration, et c3 n'est pas initialisé ou déclaré du tout.

Cela fonctionne, mais ces variables écraseront toutes celles qui existent avec le même nom en dehors de cette fonction.

Voici une version qui ne fait pas ça :

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

9 votes

@Daan Je n'avais pas assez de rep pour éditer les réponses quand j'ai écrit cette réponse...en 2011.

3 votes

IE7 ? Je pense que nous devrions arrêter de perdre du temps à écrire du code pour cela, les gens n'arrêteront pas d'utiliser cette vieille technologie à moins que nous, les développeurs, les y obligions !

0 votes

@RonanDejhero ne fonctionne-t-il pas dans IE7 ? Je ne me souviens pas si j'ai testé dans ce navigateur particulier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X