Bir dizeyi JavaScript'te Base64'e nasıl kodlayabilirsiniz?


810

Bir Base64 dizeye bir PNG resmi kodlayabilirsiniz bir PHP komut dosyası var.

Aynı şeyi JavaScript kullanarak yapmak istiyorum. Dosyaları nasıl açacağımı biliyorum, ancak kodlamayı nasıl yapacağımdan emin değilim. İkili verilerle çalışmaya alışkın değilim.


2
Javascript kullanarak base64_encode ve base64_decode için en iyi yol. Aşağıdaki bağlantılara bakın. phpjs.org/functions/base64_encode:358 phpjs.org/functions/base64_decode:357
gautamlakum 28:11

burada başka jquery eklentisi fo base64 şifreleme / şifre çözme
zahid9i

Mikrojileri kontrol edin: microjs.com/#base64
Vinod Srivastav

Yanıtlar:


866

Sen kullanabilirsiniz btoa()ve atob()ve base64 kodlamadan dönüştürmek.

Bu işlevlerin neyi kabul ettiği / geri döndüğü ile ilgili yorumlarda bir karışıklık var gibi görünüyor, bu yüzden…

  • btoa()her karakterin 8 bitlik bir baytı temsil ettiği bir "dize" kabul eder - 8 bitle temsil edilemeyen karakterler içeren bir dize iletirseniz, büyük olasılıkla kesilir . Dizeyi bir bayt dizisi olarak ele alıyorsanız bu bir sorun değildir , ancak başka bir şey yapmaya çalışıyorsanız, önce onu kodlamanız gerekir.

  • atob()her bir karakter, bir 8-bit baytlık temsil eden bir “dizesini” olarak geri dönmektedir - olan, değeri arasında olacaktır 0ve 0xff. Bu mu değil 's ASCII demek - hiçbir zaman bu fonksiyonu kullanıyorsanız muhtemelen, ikili verilerle metin olarak değil çalışmaktan bekliyoruz.

Ayrıca bakınız:


47
Bunun Safari gibi webkit tarayıcıları için de geçerli olduğunu unutmayın.
Daniel Von Fange

5
ancak iOS 4.1 ile iPhone3G'de çalışmaz. İPhone4 veya iPhone olarak ayarlandığında simülatör iPhone simülatörü üzerinde çalışır.
Grant M

29
Unicode dizeleri için özellikle dikkate alınmalıdır: developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa ve atob yalnızca ASCII tabanlı dizelerde düzgün çalışır. Bir Amerikalı olarak, muhtemelen bir fark görmeyeceksiniz ... ancak ilk kez aksanlı bir karakter kullandığınızda, kodunuz kırılacaktır.
Dan Esparza

70
Kullanmanız gereken btoa(unescape(encodeURIComponent(str))))str UFT8 ise
SET

4
Düzenlememe bak, @Triynko. Bunlar metin , nokta işlemek için kullanılmaz .
Shog9

289

Buradan :

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

}

Ayrıca, "javascript base64 encoding" araması diğer seçeneklerin çoğunu döndürür, yukarıda birincisi vardı.


3
Bu, base64 kodlaması standart olmadığında da kullanışlıdır; benim durumumda "/" karakteri kullanılmadı ve "?" Bunun yerine karakter kullanıldı, yani Chrome atob () bile gelen base64 dizelerinin kodunu çözmeyecekti.
Chris Moschini

21
Bu koda dikkat edin - dizenizi UTF-8 kodlu dize olarak yorumlamaya çalışır. İkili bir dizeye sahip olduğumuz bir durum vardı (dizedeki her karakter bir bayt olarak yorumlanmalıdır) ve bu kod verileri bozdu. Kaynağı oku, Luke.
Daniel Yankowsky

11
Çoğu ikili kodlama / kod çözme string = string.replace(/\r\n/g,"\n");için utf8 kodlama yöntemindeki şüpheli ifadeyi kaldırmasını sağlamak için gereken her şey .
Marius

7
@Marius: Neden string = string.replace(/\r\n/g,"\n");ilk başta yer alacaklarını merak ediyorum , lol. "Oh, bu dizeyi kodlayalım, ama önce neden iyi bir sebep olmadan tüm satır sonlarını rastgele normalleştirmiyoruz?" Bu kesinlikle her koşulda sınıftan çıkarılmalıdır.
Triynko

2
Ben bir javascript guru değilim, ama bu kod bir hata içeriyor gibi görünüyor: chr2 NaN ise, değeri hala ifadede kullanılır enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);. Tarayıcımda bu çalışıyor, NaN>>40'a eşit, ancak tüm tarayıcıların bunu yapıp yapmadığını bilmiyorum (ayrıca, NaN/16NaN'ye eşittir).
Ocak

117

Internet Explorer 10 ve üstü sürümler

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

Çapraz Tarayıcı

// 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.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

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

jsFiddle


Node.js ile

Normal metni Node.js'de base64'e nasıl kodlayacağınız aşağıda açıklanmıştır:

//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');

Ve base64 kodlu dizelerin kodunu şu şekilde çözersiniz:

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

Dojo.js ile

Bir bayt dizisini dojox.encoding.base64 kullanarak kodlamak için:

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

Base64 kodlu bir dizenin kodunu çözmek için:

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

bower açısal taban kurulumu64

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

3
Bu yanıt orijinal koda dayanmaktadır ve buradaki diğer yanıtlarda yayınlanan bu koda yönelik güncellemeleri İÇERMEZ.
Eugene Ryabtsev

Önerilen NodeJS çözümü kullanımdan kaldırıldı.
Vladimir Nul

94

Sunny'nin kodu, IE7'de "this" e gönderme nedeniyle kırılması dışında harika. Bu referansları "Base64" ile değiştirerek düzeltildi:

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
ooh, kötüyüm, girdiyi tarayıcı URL'sinden alıyordum; nerede | % 7C'ye dönüştürülür; dolayısıyla kodlama da yanlıştır.
Kanagavelu Sugumar

Bunun gerçekten eski olduğunu biliyorum, ama birden fazla yerde kullanılan bu işlevi gördüm, anahtar dize aslında 64 değil 65 karakter. Dize standart spec değil, önemli olduğundan emin değilim, ama sadece merak ediyordum Eğer yaparsa?
Jonathan Wagner

"katı kullanın"; 'this'i ve' with 'gibi diğer tür unsurları kıran şey ve okuduğum şeyden,' eval 'bir dayak alır. Kötüye kullanımla ilgili tüm yanlış fikirler. Şahsen JavaScript'in neden gidişattan aşağıya inmesi gerektiğini anlamıyorum, asla sıkıca bağlı ve zaten olduğundan daha karmaşık bir program olması amaçlanmamıştı. Bağlanmak istiyorsanız javascript için bir derleyici oluşturun.
Mark Giblin

Bu işlevi kullanmaya çalışıyorum ve hatayı alıyorum: Neden: org.mozilla.javascript.EcmaError: TypeError: Nesne teste teste teste işlev yerine işlev bulamıyorum .txt "teste teste teste" ile kodlamak çalışıyorum. Bu hatanın neden olduğunu bilen var mı?
PRVS

@JonathanWagner - normal kodlama için kullanılan 64 karakter vardır. 65'inci karakter, giriş dizesinin 3 ile bölünebilen bir dizi karakteri olmadığından doldurma olarak kullanılır.
Kickstart

90

Sen kullanabilirsiniz btoave (taban-64) atob(baz-64).

IE 9 ve önceki sürümler için jquery-base64 eklentisini deneyin :

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

133
Neden her şeyin bir jQuery eklentisi olması gerekiyor: c Bu sadece temel JavaScript işlevselliği, bunun DOM veya jQuery ile ilgisi yok
EaterOfCode 29:03

38
Bu temel bir işlevsellik değildir ya da çok sayıda farklı yüksek oylanmış cevap (do-it-yourself tl; dr kodu dahil) olmaz. Yani, imho bu aslında jQuery için iyi bir kullanım durumudur (bir astar, Android'in WebView'de bile çalışması bekleniyor) - zaten bir bağımlılık olsa bile.
Risadinha

1
Ben jQuery içine böyle kod snippet'leri yüklemek istiyorum çünkü onlar kontrollü bir ad alanında olacak. AMD veya CommonJS veya benzeri bir tasarım deseni kullanmıyorsanız, global ad alanınızın bir grup rastgele işlevle gerçekten dağınık olması kolaydır.
sffc

9
@Risadinha - işlevselliği dışında herhangi bir şeye bağlı değildir veya jQuery'yi genişletmez ... kelimenin tam anlamıyla kodundaki jQuery'ye yapılan tek başvurular onu jQuery nesnesine iliştiriyor ... yani jQuery'ye bağlamanın anlamı nedir ve bu nedenle jQuery kullanmak için? Sadece kendi 1 astarı olun base64.encode(...)ve base64.decode(...)... sıfır jQuery'ye özgü işlevselliği olduğunda jQuery'ye takmak kesinlikle mantıklı değil ...
Jimbo Jonny

1
jQuery talep edilmedi. Eski bir JS sorusuna geçerli bir cevap değil.
metaColin

34

Kabul edilen cevabın altındaki yorumlardan (SET ve Stefan Steiger tarafından), burada bir dizeye base64'ten / kütüphaneden bir kütüphaneye gerek olmadan nasıl kod / kod çözüleceğinin hızlı bir özeti verilmiştir.

str = "The quick brown fox jumps over the lazy dog";
b64 = btoa(unescape(encodeURIComponent(str)));
str = decodeURIComponent(escape(window.atob(b64)));

gösteri

(jQuery kitaplığını kullanır, ancak kodlama / kod çözme için kullanmaz)


Onaylamak için, bu UTF-8 karakterlerini destekliyor mu?
Crashalot

1
@Crashalot Bunun iki yıl çok geç olduğunu anlıyorum, ama evet öyle. Ben de sadece UTF8 çalışması yapan bir düzenleme sağladığınız yazarken fark ediyorum.
tycrek

Burada Node.js ile kullanmak için iyi bir çözüm arayan herkes için, bu çalışmaları onaylayabilirim. Buffer.from(b64data, 'base64').toString();
Düğümde

26

Her iki uygulamasında da birkaç hata var _utf8_decode. c1ve ifadenin c2bozuk kullanımı nedeniyle genel değişkenler olarak atanır varve c3hiç başlatılmaz veya bildirilmez.

Çalışır, ancak bu değişkenler bu işlevin dışında aynı ada sahip mevcut olanların üzerine yazar.

İşte bunu yapmayacak bir sürüm:

// 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
@Daan 2011 yılında bu yanıtı yazdığımda cevapları düzenlemek için yeterli temsilcim yoktu.
robbles

2
IE7? Sanırım bunun için kod yazmak için zaman kaybetmemeliyiz, geliştiriciler onları zorlamadıkça insanlar bu eski teknolojiyi kullanmayı bırakmayacaklar!
Rami Dabain

@RonanDejhero IE7'de çalışmıyor mu? O tarayıcıda test ettiğimi hatırlamıyorum.
robbles

1
Ne demek o IE7 işe yaramazsa, kimse umursamaz! test etmedim ve test etmeyeceğim :)
Rami Dabain

16

Sunny'nin cevabını + 1'ledim, ancak herkesin faydalı bulması durumunda kendi projem için yaptığım birkaç değişikliğe geri dönmek istedim. Temelde JSLint kadar şikayet etmiyor bu yüzden sadece orijinal kodu biraz temizledim ve ben gerçekten özel yorumlarda özel olarak işaretlenmiş yöntemleri yaptı. Ben de yani kendi projede gerekli iki yöntem eklendi decodeToHexve encodeFromHex.

Kod:

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

Başlangıçta ayrı bir ifadeye çıktı birleştirme unrolling daha iyi olacağını düşündüm, ama bir saniye için düşündüm sonra, Javascript dizeleri değişmez ve bu potansiyel olarak büyük veri blobs 4 kopya neden olur çünkü bu daha verimsiz olmalıdır büyük ikili veri dosyaları ile. Önce 4 karakteri birleştirmek ve sonra yeni bir dize oluşturmak daha güvenli bir bahis. Keşke tüm platformlarda verimli olacağından emin olabileceğim daha iyi bir dizi oluşturma yöntemini bilseydim (hatta IE6)
Marius

Başlangıçta gönderilen kodu temizlememde performansı dikkate almadım. Sadece daha okunabilir hale getirdim ve orijinaldeki yorumlarda özel olarak işaretlenmiş yöntemleri ortaya çıkaran modül desenini kullanarak gerçekten özel yaptım. Eminim performans açısından da optimize edilebilir. Ne zaman çöp toplama burada başlayacak emin değilim ve Javascript aracılığıyla büyük dosyaları karma çok yaygın değildir (ya da muhtemelen her durumda en uygun çözüm değildir).
Joe Dyndale

Komik bu kod nasıl burada yaşıyor. Bu sayfada zaten 3 farklı sürümü var.
gregn3

15

Daha yeni tarayıcıların Uint8Array öğesini dizeye kodlaması ve dizeyi Uint8Array olarak kodlaması için.

const base64 = {
    decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
    encode: b => btoa(String.fromCharCode(...new Uint8Array(b)))
};

Node.js için, dizeyi dize, Buffer veya Uint8Array kodlamak ve dize, Buffer veya Uint8Array'den Buffer'a kodunu çözmek için aşağıdakileri kullanabilirsiniz.

const base64 = {
    decode: s => Buffer.from(s, 'base64'),
    encode: b => Buffer.from(b).toString('base64')
};

13

Base64 kodlu Dize URL'sini kolay hale getirmek için JavaScript'te şu şekilde bir şey yapabilirsiniz:

// 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, '/');

Ayrıca bakınız bu Fiddle: http://jsfiddle.net/magikMaker/7bjaT/


9
Alçakgönüllülükle, kullanımının encodeURIComponentgeliştirici adına daha az çaba harcayarak üstün bir sonuçla sonuçlanabileceğini öneririm .
Pablo Fernandez

11
encodeURIComponent, base64 kodlu dizelerin uzunluğunu değiştirir ve URL'lerde base64 kullanıldığında '-' ve '_' yerine '+' ve '/' yerine standart uygulama kullanılır (örn. docs.python.org/library/base64.html#base64 .urlsafe_b64encode ). Üzülmeye gerek yok.
natevw

12

Bunun ham Unicode dizeleri için uygun olmadığını lütfen unutmayın! Buradaki Unicode bölümüne bakın .

Kodlama için sözdizimi

var encodedData = window.btoa(stringToEncode);

Kod çözme için sözdizimi

var decodedData = window.atob(encodedData);


1
Unicode bölümüne doğrudan bağlantı: developer.mozilla.org/en-US/docs/Web/API/…
TomTasche

12

El ile yeniden yazdım, bu kodlama ve kod çözme yöntemleri, onaltılı bir hariç, platformlar arası / tarayıcı uyumluluğu için modüler bir formata ve ayrıca gerçek özel kapsam belirleme ile ve kullanır btoave atobkullanmaktan ziyade hız nedeniyle var ise kendi kodlaması:

https://gist.github.com/Nijikokun/5192472

Kullanımı:

base64.encode(/* String */);
base64.decode(/* String */);

utf8.encode(/* String */);
utf8.decode(/* String */);

12

Bu soru ve cevapları beni doğru yöne yönlendirdi.
Özellikle unicode atob ve btoa ile "vanilya" kullanılamaz ve bu günlerde HER ŞEY unicode olduğunu ..

Doğrudan Mozilla'dan, bu amaçla iki güzel işlev (içindeki unicode ve html etiketleri ile test edildi)

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"

Bu işlevler, btoa ve atob yorumlayıcı dışında yürütüldüğünden, özel bir javascript işlevi kullanılarak ham base64 kod çözme işlemine kıyasla yıldırım hızında çalışacaktır.

Eski IE ve eski cep telefonlarını (iphone 3 gibi) görmezden geliyorsanız, bu iyi bir çözüm olmalıdır.


10

HTML görüntü nesnesini kodlamanız gerekiyorsa, aşağıdaki gibi basit bir işlev yazabilirsiniz:

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
}  

Görüntünün base64 değerini kimliğe göre almak için:

function getBase64ImageById(id){  
  return getBase64Image(document.getElementById(id));  
} 

daha fazlası burada


Evet ve var img = new Image (); img.src = "../images/myPic.png";
pdschuller

7

Şu anda kullandığım window.atob+ için küçültülmüş bir çoklu dolgu ile katkıda bulunma 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})})();

6

Daha doğrusu dan bas64 şifreleme / şifre çözme yöntemleri kullanmak istiyorum CryptoJS , en iyi uygulamaları ve kalıplarını kullanarak JavaScript uygulanan standart ve güvenli kriptografik algoritmalar için en popüler kütüphanede.


6

@ User850789'un birinin AngularJS Fabrikası sürümü:

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

6

Benim bir proje için base64 olarak UTF-8 dizesinin kodlanması gerekiyordu. Buradaki cevapların çoğu UTF-8'e dönüştürürken UTF-16 vekil çiftlerini düzgün bir şekilde ele almıyor gibi görünüyor, bu yüzden tamamlama uğruna, çözümümü göndereceğim:

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

Kodun tam olarak test edilmediğini unutmayın. strToUTF8Base64('衠衢蠩蠨')Çevrimiçi kodlama aracının çıktısıyla ( https://www.base64encode.org/ ) benzer şeyler dahil bazı girdileri test ettim .


5

Projem için hala IE7'yi desteklemem ve kodlamak için büyük girdilerle çalışmam gerekiyor.

Joe Dyndale tarafından önerilen koda dayanarak ve Marius tarafından yorumda önerildiği gibi, sonucu dize yerine bir dizi ile yapılandırarak IE7 ile performansı iyileştirmek mümkündür.

İşte kodlama örneği:

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

5

Biraz daha fazla çalışma yaparken, yüksek performanslı bir yerel çözüm istiyorsanız, kullanabileceğiniz bazı HTML5 işlevleri vardır.

Verilerinizi a içine alabilirseniz, bir URL almak Blobiçin FileReader.readAsDataURL () işlevini kullanabilir data://ve base64 verilerine ulaşmak için önünü kesebilirsiniz .

+Karakterlerin data://URL için kaçıp kaçmadığından emin değilim, ancak verileri urldecode için daha fazla işlem yapmanız gerekebilir , ancak bu oldukça önemsiz olmalıdır.


5

Eğer dojo kullanıyorsanız, bize base64 kodlamak veya kod çözmek için doğrudan bir yol verir.

Bunu dene:-

Bir bayt dizisini dojox.encoding.base64 kullanarak kodlamak için:

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

Base64 kodlu bir dizenin kodunu çözmek için:

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

3

Kullanabilirsiniz window.btoave window.atob...

const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
const decoded = window.atob(encoded); // decode the string

Muhtemelen MDN'nin olduğu şekilde kullanmak işinizi en iyi şekilde yapabilir ... Ayrıca unicode'u kabul etmek ... bu iki basit işlevi kullanarak:

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

3

İşte olan CANLI DEMO arasında atob()ve btoa()fonksiyonları inşa 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>

2

Js-base64 kitaplığını şu şekilde kullanın:

btoa () emojilerle çalışmaz

var str = "I was funny 😂";
console.log("Original string:", str);

var encodedStr = Base64.encode(str)
console.log("Encoded string:", encodedStr);

var decodedStr = Base64.decode(encodedStr)
console.log("Decoded string:", decodedStr);
<script src="https://cdn.jsdelivr.net/npm/js-base64@2.5.2/base64.min.js"></script>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.