Apakah ada metode dalam JavaScript yang dapat digunakan untuk menyandikan dan mendekode string menggunakan pengkodean base64?
Apakah ada metode dalam JavaScript yang dapat digunakan untuk menyandikan dan mendekode string menggunakan pengkodean base64?
Jawaban:
Beberapa browser seperti Firefox, Chrome, Safari, Opera dan IE10 + dapat menangani Base64 secara asli. Lihatlah pertanyaan Stackoverflow ini . Ini menggunakan btoa()
dan atob()
fungsinya .
Untuk JavaScript sisi server (Node), Anda dapat menggunakan Buffer
s untuk mendekode.
Jika Anda mencari solusi lintas-peramban, ada pustaka yang ada seperti CryptoJS atau kode seperti:
http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
Dengan yang terakhir, Anda perlu menguji fungsi secara menyeluruh untuk kompatibilitas lintas browser. Dan kesalahan sudah dilaporkan .
new Buffer('Hello, world!').toString('base64');
new Buffer('SGVsbG8sIHdvcmxkIQ==', 'base64').toString('ascii');
(sumber)
new Buffer(string)
sudah usang. Buffer.from(jwt.split('.')[1], 'base64').toString()
Di browser berbasis Gecko / WebKit (Firefox, Chrome dan Safari) dan Opera, Anda dapat menggunakan btoa () dan atob () .
Jawaban asli: Bagaimana Anda bisa menyandikan string ke Base64 di 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!"
Inilah cara Anda menyandikan teks normal ke base64 di 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');
Dan di sini adalah bagaimana Anda mendekodekan string yang disandikan base64:
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();
Untuk menyandikan larik byte menggunakan dojox.encoding.base64:
var str = dojox.encoding.base64.encode(myByteArray);
Untuk memecahkan kode string yang disandikan 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=');
}]);
Jika Anda ingin mempelajari lebih lanjut tentang bagaimana base64 dikodekan secara umum, dan dalam JavaScript khususnya, saya akan merekomendasikan artikel ini: Ilmu komputer dalam JavaScript: pengkodean Base64
c2
dan kemungkinan c1
dan c3
sehingga tidak akan bekerja dengan "use strict"
seperti dijelaskan di atas.
Ini adalah versi posting Sniper yang diperketat. Ini menganggap string base64 terbentuk dengan baik tanpa carriage return. Versi ini menghilangkan beberapa loop, menambahkan &0xff
perbaikan dari Yaroslav, menghilangkan tertinggal nol, ditambah sedikit kode 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;
};
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++;
Fungsi Dekode JavaScript Base64 pendek dan cepat tanpa Failsafe:
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 )));
}
Proyek php.js memiliki implementasi JavaScript dari banyak fungsi PHP. base64_encode
dan base64_decode
sudah termasuk.
Apakah ada yang mengatakan kode golf? =)
Berikut ini adalah upaya saya untuk meningkatkan cacat saya sambil mengejar ketinggalan zaman. Disediakan untuk kenyamanan Anda.
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;
}
Apa yang sebenarnya saya kejar adalah implementasi asinkron dan yang mengejutkan saya ternyata forEach
bertentangan dengan $([]).each
implementasi metode JQuery yang sangat sinkron.
Jika Anda juga memiliki gagasan gila dalam pikiran penundaan 0 window.setTimeout
akan menjalankan decode base64 asynchronous dan menjalankan fungsi callback dengan hasil ketika selesai.
function decode_base64_async(s, cb) {
setTimeout(function () { cb(decode_base64(s)); }, 0);
}
@Toothbrush menyarankan "indeks string seperti array", dan singkirkan split
. Rutin ini tampaknya sangat aneh dan tidak yakin seberapa kompatibel itu, tapi itu mengenai birdie lain jadi mari kita memilikinya.
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;
}
Ketika mencoba untuk menemukan informasi lebih lanjut tentang string JavaScript sebagai array saya menemukan tip pro ini menggunakan /./g
regex untuk melangkah melalui string. Ini mengurangi ukuran kode bahkan lebih dengan mengganti string di tempat dan menghilangkan kebutuhan menjaga variabel kembali.
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);
});
}
Namun jika Anda mencari sesuatu yang sedikit lebih tradisional mungkin yang berikut ini lebih sesuai dengan selera Anda.
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;
}
Saya tidak memiliki masalah nol tertinggal sehingga ini dihapus untuk tetap di bawah standar tetapi harus dengan mudah diselesaikan dengan a trim()
atau atrimRight()
jika Anda mau, jika ini menimbulkan masalah bagi Anda.
yaitu.
return r.trimRight();
Hasilnya adalah string byte ascii, jika Anda memerlukan unicode, yang paling mudah adalah escape
string byte yang kemudian dapat didekodekan dengan decodeURIComponent
untuk menghasilkan string unicode.
function decode_base64_usc(s) {
return decodeURIComponent(escape(decode_base64(s)));
}
Karena escape
sudah tidak digunakan lagi, kita dapat mengubah fungsi kita untuk mendukung unicode secara langsung tanpa perlu escape
atau String.fromCharCode
kita dapat menghasilkan %
string yang lolos yang siap untuk decoding 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
menggunakan string, karena Anda dapat mengindeks string JavaScript seperti array. s.split('').forEach(function ...
dapat digantikan oleh [].forEach.call(s, function ...
. Seharusnya lebih cepat, karena tidak harus membelah string.
Saya telah mencoba rutinitas Javascript di phpjs.org dan mereka telah bekerja dengan baik.
Saya pertama kali mencoba rutinitas yang disarankan dalam jawaban yang dipilih oleh Ranhiru Cooray - http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
Saya menemukan bahwa mereka tidak bekerja dalam semua keadaan. Saya menulis uji kasus di mana rutinitas ini gagal dan mempostingnya ke GitHub di:
https://github.com/scottcarter/base64_javascript_test_data.git
Saya juga memposting komentar ke posting blog di ntt.cc untuk mengingatkan penulis (menunggu moderasi - artikel sudah tua jadi tidak yakin apakah komentar akan diposting).
Di Node.js kita bisa melakukannya dengan cara sederhana
var base64 = 'SGVsbG8gV29ybGQ='
var base64_decode = new Buffer(base64, 'base64').toString('ascii');
console.log(base64_decode); // "Hello World"
Untuk kerangka kerja JavaScripts di mana tidak ada atob
metode dan jika Anda tidak ingin mengimpor perpustakaan eksternal, ini adalah fungsi pendek yang melakukannya.
Ini akan mendapatkan string yang berisi nilai yang disandikan Base64 dan akan mengembalikan array byte yang didekodekan (di mana array byte diwakili sebagai array angka di mana setiap angka adalah bilangan bulat antara 0 dan 255 inklusif).
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};
}
Sumber yang digunakan: RFC-4648 Bagian 4