Base64 kodlama ve kod çözme istemci tarafı Javascript


Yanıtlar:


214

Firefox, Chrome, Safari, Opera ve IE10 + gibi bazı tarayıcılar Base64'ü yerel olarak kullanabilir. Bu Stackoverflow sorusuna bir göz atın . Kullanıyor btoa()ve atob()işlevleri .

Sunucu tarafı JavaScript (Düğüm) Bufferiçin kod çözmek için s kullanabilirsiniz .

Bir tarayıcılar arası çözüm arıyorsanız, CryptoJS gibi kodlar veya aşağıdaki gibi kodlar vardır :

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

İkincisi ile, çapraz tarayıcı uyumluluğu için işlevi iyice test etmeniz gerekir. Ve hata zaten bildirildi .


1
Date URI şeması ile base64 bir SVG kodlamak için bu yöntemi kullandım. Sürpriz: bu işlev her karakteri urlencodes, bu yüzden bu hatalı biçimlendirilmiş XML'i hedefe alıyorum:% 3C% 3Fxml% 20vers%% 3D% 271.0% 27% 20% 3F% 3E% 3Csvg% 20xmlns% 3D% 27http% ...
Dereckson

21
Node.js new Buffer('Hello, world!').toString('base64'); new Buffer('SGVsbG8sIHdvcmxkIQ==', 'base64').toString('ascii');
Base64'i

Ve URL güvenli yapmak istersem?
anddero

1
5+ düğümünde, kullanımdan new Buffer(string)kaldırıldığı gibi Buffer.from kullanın . Buffer.from(jwt.split('.')[1], 'base64').toString()
Ray Foss

63

Gecko / WebKit tabanlı tarayıcılarda (Firefox, Chrome ve Safari) ve Opera'da btoa () ve atob () kullanabilirsiniz .

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


Bu bir hayat kurtarıcı. Çok büyük base64 kodlu dizeleri çözmek için birkaç farklı uygulama kullandım ve sonuç her zaman yanlıştı. atob () harika çalışıyor!
b2238488

15
Küçük nitpick: Opera, Gecko veya Webkit'e dayanmaz, Presto adlı kendi oluşturma motorunu kullanır.
Peter Olson

Vay canına, bunun için teşekkürler. Bu tarayıcılarda yerel bir base64 kodlayıcı olduğunu bilmiyordum!
Rob Porter

5
@PeterOlson Artık değil :)
Mustafa

1
Bunun eski bir yazı olduğunu anlıyorum, ancak @ b2238488'in kaygısı hakkında, her tokenin uzunluğunun 4'ün bir katı olması için base64 dizesini bölebilir ve bunları ayrı olarak çözebilirsiniz. Sonuç, tüm dizeyi bir kerede deşifre etmekle aynı olacaktır.
nyuszika7h

56

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ı

AMD, CommonJS, Nodejs ve Tarayıcılar için yeniden yazılmış ve modülerleştirilmiş UTF-8 ve Base64 Javascript Kodlama ve Kod Çözme Kitaplıkları / Modülleri. Çapraz tarayıcı uyumlu.


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

Ama nasıl?

Base64'ün genel olarak ve özellikle JavaScript'te nasıl kodlandığı hakkında daha fazla bilgi edinmek isterseniz, bu makaleyi öneriyorum: JavaScript'te bilgisayar bilimi: Base64 kodlaması


1
FYI: Çapraz tarayıcı sürümünde bazı kötü sızıntılar var c2ve muhtemelen c1ve c3bu yüzden "use strict"yukarıda tanımlandığı gibi çalışmayacak .
Campbeln

41

İşte Sniper'ın gönderisinin sıkılmış bir versiyonu. Taşıyıcı dönüşü olmadan iyi biçimlendirilmiş base64 dizesini varsayar. Bu sürüm birkaç döngüyü &0xffortadan kaldırır, Yaroslav'dan düzeltme ekler, sondaki sıfırları ve biraz da golf kodunu ortadan kaldırır.

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

5
Daha az bayt; DdecodeBase64=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};
Der Hochstapler

Evet ama sadece ASCII ile çalışıyor. Örneğin Cyr karakterleri karışır.
Martin Kovachev

@MartinKovachev, Cyr karakterleri ve karşılık gelen base64 kodlaması ile örnek metin içeren yeni bir yorum gönderebilir misiniz? Belki kodu yerleştirmek için düzeltebiliriz.
broc.seib

İşte: böyle bir şey: тестова фраза
Martin Kovachev

2
@OliverSalzburg Daha az kod tablosu oluşturmak :):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++;
Mike

34

Başarısız Kısa ve hızlı Base64 JavaScript Kod Çözme İşlevi:

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

6
Opera 11.62 '% 256' bölümü ile sorun yaşıyor gibi görünüyor. '& 0xff' ile değiştirmek çalışmasını sağlar.
Yaroslav Stavnichiy

Tyk sanal uç nokta javascript kodu '\ x00' bölümü ile sorun yaşıyor gibi görünüyor. R = r.replace (/ \ x00 / g, '') ile değiştirerek çalışmasını
sağlayın


11

Php.js projesi PHP'nin fonksiyonlarının çoğunun JavaScript uygulamaları bulunmaktadır. base64_encodeve base64_decodedahildir.


php.js tüm kötülüklerin enkarnasyonudur ve cehennemdeki kendi katmanına aittir. Veba gibi önlemek. (Daha fazla bilgi: softwareengineering.stackexchange.com/questions/126671/… )
Coreus

Bu bağlantıdaki battaniye iddiasını destekleyen pek fazla bir şey göremiyorum, @Coreus. Akıllıca veya başlangıç ​​noktası olarak, PHP'de nasıl yapacağınızı bildiğiniz bir şey için JS'deki eşdeğer mantığı bulmanın mükemmel kabul edilebilir bir yoludur.
ceejayoz

9

Birisi kod golf dedi mi? =)

Aşağıdakileri yakalarken handikapımı geliştirmeye çalışıyorum. Size kolaylık sağlamak için tedarik edilir.

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

Aslında daha sonra olduğum zaman zaman uyumsuz bir uygulama ve forEachJQuery $([]).eachyöntem uygulama aksine çok zaman uyumlu olduğu için sürpriz oldu .

Aklınızda bu tür çılgın kavramlar da varsa, 0 gecikmesi window.setTimeoutbase64 kod çözme işlemini eşzamansız olarak çalıştırır ve bittiğinde sonuçla geri arama işlevini yürütür.

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

@ Diş fırçası önerdi "dizini bir dizi gibi dizin" ve kurtulmak split. Bu rutin gerçekten tuhaf görünüyor ve ne kadar uyumlu olacağından emin değil, ama başka bir kuşa çarptı, hadi sahip olalım.

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

Bir dizi olarak JavaScript dizesi hakkında daha fazla bilgi bulmaya çalışırken ben /./gbir dize adım atmak için bir regex kullanarak bu pro ipucu tökezledi . Bu, dizeyi yerinde değiştirerek ve bir dönüş değişkeni tutma ihtiyacını ortadan kaldırarak kod boyutunu daha da azaltır.

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

Bununla birlikte, biraz daha geleneksel bir şey arıyorsanız belki de aşağıdaki zevkinize göre.

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

Bu par altında kalmak için kaldırıldı, ancak bu sizin için bir sorun teşkil ederse , bir trim()veya bir trimRight()tercih ederseniz kolayca çözülmelidir .

yani.

return r.trimRight();

Not:

Sonuç bir ascii bayt dizesidir, eğer unicode'a ihtiyacınız varsa en kolay olanı escapedaha sonra decodeURIComponentunicode dizgiyi üretmek için deşifre edilebilecek bayt dizesidir.

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

Kullanımdan escapekaldırıldığı için, unicode'u doğrudan desteklemeye gerek duymadan fonksiyonumuzu değiştirebiliriz escapeveya URI kod çözme için hazır String.fromCharCodebir %kaçan dize üretebiliriz .

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!


3
splitDizi gibi bir JavaScript dizesini dizine ekleyebileceğiniz için dizeye ihtiyacınız yoktur . s.split('').forEach(function ...ile değiştirilebilir [].forEach.call(s, function .... Dizeyi bölmek zorunda olmadığı için çok daha hızlı olmalı.
Diş fırçası

"Daha geleneksel" olan benim için tamamen kırılmıştı - orijinal metnin izleri boyunca serpilmiş bozuk bir karışıklık yarattı. Chrome'da.
Steve Bennett

@Steve Bennett Kromdaki tüm varyantları test ettim ... işe yarıyor. Başarısız olan örnek bir base64 dizesi sağlayabilir misiniz?
nickl-

Üç yıl sonra? Ha. Bunun için neye ihtiyacım olduğunu bile hatırlamıyorum.
Steve Bennett

6

Ben phpjs.org Javascript rutinleri denedim ve onlar iyi çalıştı.

Önce Ranhiru Cooray tarafından seçilen cevapta önerilen rutinleri denedim - http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

Her koşulda çalışmadığını gördüm. Bu rutinlerin başarısız olduğu bir test senaryosu yazdım ve GitHub'a şu adresten gönderdim:

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

Ayrıca yazarı uyarmak için ntt.cc de blog gönderisine bir yorum yayınladım (ılımlılık bekliyor - makale eski bu yüzden yorum gönderilecek emin değilim).


1

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.


1

Node.js'de bunu basit bir şekilde yapabiliriz

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

console.log(base64_decode); // "Hello World"

0

Herhangi bir atobyöntemin olmadığı JavaScripts çerçeveleri için ve harici kütüphaneleri içe aktarmak istemiyorsanız, bunu yapan kısa bir işlevdir.

Base64 kodlu değeri içeren bir dize alır ve kodu çözülmüş bir bayt dizisi döndürür (bayt dizisi, her sayının 0 ile 255 arasında bir tam sayı olduğu sayı dizisi olarak temsil edilir).

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

Kullanılan kaynaklar: RFC-4648 Bölüm 4

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.