JavaScriptに、base64エンコーディングを使用して文字列をエンコードおよびデコードするために使用できるメソッドはありますか?
JavaScriptに、base64エンコーディングを使用して文字列をエンコードおよびデコードするために使用できるメソッドはありますか?
回答:
Firefox、Chrome、Safari、Opera、IE10 +などの一部のブラウザーは、Base64をネイティブで処理できます。このStackoverflowの質問をご覧ください。使用btoa()
してatob()
機能します。
サーバーサイドJavaScript(ノード)の場合、Buffer
sを使用してデコードできます。
クロスブラウザーソリューションを使用している場合は、CryptoJSなどの既存のライブラリまたは次のようなコードがあります。
http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
後者の場合、ブラウザー間の互換性を確保するために関数を徹底的にテストする必要があります。そしてエラーはすでに報告されています。
new Buffer('Hello, world!').toString('base64');
new Buffer('SGVsbG8sIHdvcmxkIQ==', 'base64').toString('ascii');
ソース)
new Buffer(string)
非推奨のBuffer.fromを使用します。Buffer.from(jwt.split('.')[1], 'base64').toString()
// 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!"
Node.jsで通常のテキストをbase64にエンコードする方法を次に示します。
//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');
そして、base64でエンコードされた文字列をデコードする方法を次に示します。
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();
dojox.encoding.base64を使用してバイトの配列をエンコードするには:
var str = dojox.encoding.base64.encode(myByteArray);
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=');
}]);
base64の一般的なエンコード方法、特にJavaScriptについて詳しく知りたい場合は、この記事をお勧め します。JavaScriptのコンピューターサイエンス:Base64エンコード
c2
、おそらくc1
とc3
、それは動作しませんので、"use strict"
上記定義した通りです。
こちらはスナイパーの投稿の引き締めバージョンです。改行なしの整形式のbase64文字列を想定しています。このバージョンでは、いくつかのループが削除され、&0xff
Yaroslavからの修正が追加され、末尾のヌルが削除され、さらにコードのゴルフが少し追加されています。
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++;
フェイルセーフなしの短くて速いBase64 JavaScriptデコード関数:
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 )));
}
php.jsのプロジェクトはPHPの機能の多くのJavaScriptの実装を持っています。base64_encode
とbase64_decode
含まれています。
誰かがコードゴルフと言いましたか?=)
以下は、時代に追いついてハンディキャップを改善しようという私の試みです。あなたの便宜のために提供されます。
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;
}
私が実際に求めていたのは非同期実装であり、驚いたことに forEach
、JQueryの$([]).each
メソッド実装は非常に同期的であることがわかりました。
このような狂った概念も念頭に置いていた場合、遅延0 window.setTimeout
はbase64デコードを非同期に実行し、コールバック関数を実行して結果を返します。
function decode_base64_async(s, cb) {
setTimeout(function () { cb(decode_base64(s)); }, 0);
}
@Toothbrushは、「配列のような文字列にインデックスを付ける」ことを提案し、 split
。このルーチンは非常に奇妙に見え、互換性がどれほどかはわかりませんが、別のバーディーにヒットするので、それを試してみましょう。
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;
}
JavaScript文字列の詳細情報を配列として見つけようとしているときに、私はこのプロのヒントを使ってつまずきました /./g
正規表現をして文字列をステップ実行する。これにより、文字列を所定の位置に置き換え、戻り変数を保持する必要がなくなるため、コードサイズがさらに削減されます。
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);
});
}
しかし、もしあなたがもう少し伝統的なものを探していたなら、おそらく以下はあなたの好みにもっと合っているでしょう。
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;
}
後続のnullの問題はなかったので、これは標準以下にとどまるために削除されましたが、簡単に解決する必要があります trim()
またはatrimRight()
、問題が発生し場合できます。
すなわち。
return r.trimRight();
結果はASCIIバイト文字列です。Unicodeが必要な場合、最も簡単なのはescape
バイト文字列で、これをデコードしdecodeURIComponent
てUnicode文字列を生成できます。
function decode_base64_usc(s) {
return decodeURIComponent(escape(decode_base64(s)));
}
以来は、escape
私たちがを必要とせずに、直接ユニコードサポートするために、当社の機能を変更することができ廃止予定されているescape
か、String.fromCharCode
私たちが生産することができます%
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
配列のようにJavaScript文字列にインデックスを付けることができるため、文字列を使用する必要はありません。s.split('').forEach(function ...
で置き換えることができます[].forEach.call(s, function ...
。文字列を分割する必要がないため、はるかに高速になります。
私はphpjs.orgでJavascriptルーチンを試してみましたが、うまく機能しました。
私は最初にRanhiru Coorayが選んだ答えで提案されているルーチンを試しました- http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
私はそれらがすべての状況で機能したわけではないことを発見しました。これらのルーチンが失敗するテストケースを書き、GitHubに投稿しました。
https://github.com/scottcarter/base64_javascript_test_data.git
私はまた、作者に警告するためにntt.ccのブログ投稿にコメントを投稿しました(モデレートを待っています-記事が古く、コメントが投稿されるかどうか不明です)。
Node.jsでは、簡単な方法でそれを行うことができます
var base64 = 'SGVsbG8gV29ybGQ='
var base64_decode = new Buffer(base64, 'base64').toString('ascii');
console.log(base64_decode); // "Hello World"
ないJavaScriptフレームワークの場合 atob
メソッド、外部ライブラリをインポートしたくない場合の場合、これはそれを行う短い関数です。
Base64でエンコードされた値を含む文字列を取得し、デコードされたバイトの配列を返します(バイトの配列は数値の配列として表され、各数値は0〜255の整数です)。
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};
}
使用されるリソース:RFC-4648セクション4