Existe-t-il des méthodes en JavaScript qui pourraient être utilisées pour coder et décoder une chaîne en utilisant le codage base64?
Existe-t-il des méthodes en JavaScript qui pourraient être utilisées pour coder et décoder une chaîne en utilisant le codage base64?
Réponses:
Certains navigateurs tels que Firefox, Chrome, Safari, Opera et IE10 + peuvent gérer Base64 de manière native. Jetez un oeil à cette question Stackoverflow . Il utilise btoa()
et atob()
fonctionne .
Pour JavaScript côté serveur (Node), vous pouvez utiliser Buffer
s pour décoder.
Si vous optez pour une solution multi-navigateur, il existe des bibliothèques existantes comme CryptoJS ou du code comme:
http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
Avec ce dernier, vous devez tester minutieusement la fonction pour la compatibilité entre les navigateurs. Et une erreur a déjà été signalée .
new Buffer('Hello, world!').toString('base64');
new Buffer('SGVsbG8sIHdvcmxkIQ==', 'base64').toString('ascii');
(source)
new Buffer(string)
est déconseillé. Buffer.from(jwt.split('.')[1], 'base64').toString()
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?
// 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!"
Voici comment vous encodez 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 décoder les chaînes encodées en base64:
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();
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 codée en 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=');
}]);
Si vous souhaitez en savoir plus sur la façon dont le codage base64 est en général, et en JavaScript en particulier, je recommanderais cet article: Informatique en JavaScript: codage Base64
c2
et probablement c1
et c3
donc elle ne fonctionnera pas avec "use strict"
comme défini ci-dessus.
Voici une version resserrée du post de Sniper. Il suppose une chaîne base64 bien formée sans retour chariot. Cette version élimine quelques boucles, ajoute le &0xff
correctif de Yaroslav, élimine les null à la fin, plus un peu de golf de code.
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;
};
decodeBase64=function(f){var g={},b=65,d=0,a,c=0,h,e="",k=String.fromCharCode,l=f.length;for(a="";91>b;)a+=k(b++);a+=a.toLowerCase()+"0123456789+/";for(b=0;64>b;b++)g[a.charAt(b)]=b;for(a=0;a<l;a++)for(b=g[f.charAt(a)],d=(d<<6)+b,c+=6;8<=c;)((h=d>>>(c-=8)&255)||a<l-2)&&(e+=k(h));return e};
var g={},k=String.fromCharCode,i;for(i=0;i<64;)g[k(i>61?(i&1)*4|43:i+[65,71,-4][i/26&3])]=i++;
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;
}
function b64_to_utf8( str ) {
return decodeURIComponent(escape(window.atob( str )));
}
Le projet php.js a des implémentations JavaScript de nombreuses fonctions PHP. base64_encode
et base64_decode
sont inclus.
Quelqu'un a-t-il dit le code golf? =)
Ce qui suit est ma tentative d'améliorer mon handicap tout en rattrapant le 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 cherchais en fait était une implémentation asynchrone et à ma grande surprise, il s'avère forEach
que contrairement à l' $([]).each
implémentation de la méthode JQuery, elle est très synchrone.
Si vous aviez également des notions aussi folles à l'esprit, un retard de 0 window.setTimeout
exécutera le décodage 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 je ne sais pas à quel point elle sera compatible, mais elle frappe un autre birdie, alors allons-y.
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;
}
En essayant de trouver plus d'informations sur la chaîne JavaScript en tant que tableau, je suis tombé sur cette astuce de pro en utilisant une /./g
expression régulière 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 le besoin 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 cherchiez quelque chose d'un peu plus traditionnel, peut-être que ce qui suit est plus à votre goût.
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 problème null de fin, donc cela a été supprimé pour rester sous le pair mais il devrait facilement être résolu avec un trim()
ou un trimRight()
si vous préférez, si cela vous pose un problème.
c'est à dire.
return r.trimRight();
Le résultat est une chaîne d'octets ascii, si vous avez besoin d'unicode, le plus simple est 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)));
}
Comme il escape
est obsolète, nous pourrions changer notre fonction pour prendre en charge directement unicode sans avoir besoin de escape
ou String.fromCharCode
nous pouvons produire une %
chaîne d'échappement 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);
}));
}
nJoy!
split
la chaîne, car vous pouvez indexer une chaîne JavaScript comme un tableau. s.split('').forEach(function ...
peut être remplacé par [].forEach.call(s, function ...
. Cela devrait être beaucoup plus rapide, car il n'a pas à diviser la chaîne.
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 en toutes circonstances. J'ai rédigé un cas de test où ces routines échouent et les ai publiées sur GitHub à l'adresse:
https://github.com/scottcarter/base64_javascript_test_data.git
J'ai également posté un commentaire sur le blog sur 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é).
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"
Pour les frameworks JavaScripts où il n'y a pas de atob
méthode et au cas où vous ne souhaitez pas importer de bibliothèques externes, c'est une fonction courte qui le fait.
Il obtiendrait une chaîne qui contient une valeur encodée en Base64 et retournera un tableau décodé d'octets (où le tableau d'octets est représenté comme un tableau de nombres où chaque nombre est un entier compris entre 0 et 255 inclus).
function fromBase64String(str) {
var alpha =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var value = [];
var index = 0;
var destIndex = 0;
var padding = false;
while (true) {
var first = getNextChr(str, index, padding, alpha);
var second = getNextChr(str, first .nextIndex, first .padding, alpha);
var third = getNextChr(str, second.nextIndex, second.padding, alpha);
var fourth = getNextChr(str, third .nextIndex, third .padding, alpha);
index = fourth.nextIndex;
padding = fourth.padding;
// ffffffss sssstttt ttffffff
var base64_first = first.code == null ? 0 : first.code;
var base64_second = second.code == null ? 0 : second.code;
var base64_third = third.code == null ? 0 : third.code;
var base64_fourth = fourth.code == null ? 0 : fourth.code;
var a = (( base64_first << 2) & 0xFC ) | ((base64_second>>4) & 0x03);
var b = (( base64_second<< 4) & 0xF0 ) | ((base64_third >>2) & 0x0F);
var c = (( base64_third << 6) & 0xC0 ) | ((base64_fourth>>0) & 0x3F);
value [destIndex++] = a;
if (!third.padding) {
value [destIndex++] = b;
} else {
break;
}
if (!fourth.padding) {
value [destIndex++] = c;
} else {
break;
}
if (index >= str.length) {
break;
}
}
return value;
}
function getNextChr(str, index, equalSignReceived, alpha) {
var chr = null;
var code = 0;
var padding = equalSignReceived;
while (index < str.length) {
chr = str.charAt(index);
if (chr == " " || chr == "\r" || chr == "\n" || chr == "\t") {
index++;
continue;
}
if (chr == "=") {
padding = true;
} else {
if (equalSignReceived) {
throw new Error("Invalid Base64 Endcoding character \""
+ chr + "\" with code " + str.charCodeAt(index)
+ " on position " + index
+ " received afer an equal sign (=) padding "
+ "character has already been received. "
+ "The equal sign padding character is the only "
+ "possible padding character at the end.");
}
code = alpha.indexOf(chr);
if (code == -1) {
throw new Error("Invalid Base64 Encoding character \""
+ chr + "\" with code " + str.charCodeAt(index)
+ " on position " + index + ".");
}
}
break;
}
return { character: chr, code: code, padding: padding, nextIndex: ++index};
}
Ressources utilisées: RFC-4648 Section 4