JavaScript プログラミング講座

 

Base64 とは?

 


■Base64 とは?


Base64 は、65 種類の文字を使って、バイナリデータを、文字列で表現する事ができます。
 
テキストフォーマットの一種です。
 
基本的なエンコード部分には、英数字『 a-zA-Z0-9 』と加算記号『 + 』、スラッシュ『 / 』の、合計 64 文字を使用します。
 
終端で発生する、余りを埋めるのに、等号『 = 』を使用します。
 
Base64 のサイズは、バイナリのサイズと比較すると、約 4/3 倍に増えます
 
Base64 のサイズは、必ず 4 の倍数となります。
 
Base64 は、メールの添付ファイルなどで利用されています。
 


 

Base64 のフォーマットについて

 
 


■Base64 変換テーブル

 
番号 文字 番号 文字 番号 文字
0 "A" (0x41) 26 "a" (0x61) 52 "0" (0x30)
1 "B" (0x42) 27 "b" (0x62) 53 "1" (0x31)
2 "C" (0x43) 28 "c" (0x63) 54 "2" (0x32)
3 "D" (0x44) 29 "d" (0x64) 55 "3" (0x33)
4 "E" (0x45) 30 "e" (0x65) 56 "4" (0x34)
5 "F" (0x46) 31 "f" (0x66) 57 "5" (0x35)
6 "G" (0x47) 32 "g" (0x67) 58 "6" (0x36)
7 "H" (0x48) 33 "h" (0x68) 59 "7" (0x37)
8 "I" (0x49) 34 "i" (0x69) 60 "8" (0x38)
9 "J" (0x4a) 35 "j" (0x6a) 61 "9" (0x39)
10 "K" (0x4b) 36 "k" (0x6b) 62 "+" (0x2b)
11 "L" (0x4c) 37 "l" (0x6c) 63 "/" (0x2f)
12 "M" (0x4d) 38 "m" (0x6d)
13 "N" (0x4e) 39 "n" (0x6e)
14 "O" (0x4f) 40 "o" (0x6f)
15 "P" (0x50) 41 "p" (0x70)
16 "Q" (0x51) 42 "q" (0x71)
17 "R" (0x52) 43 "r" (0x72)
18 "S" (0x53) 44 "s" (0x73)
19 "T" (0x54) 45 "t" (0x74)
20 "U" (0x55) 46 "u" (0x75)
21 "V" (0x56) 47 "v" (0x76)
22 "W" (0x57) 48 "w" (0x77)
23 "X" (0x58) 49 "x" (0x78)
24 "Y" (0x59) 50 "y" (0x79)
25 "Z" (0x5a) 51 "z" (0x7a)
 

■バイナリから Base64 にエンコードする

 
■Base64 の総サイズを計算する
 
バイナリのサイズを 3 で割り、小数を切り上げます。
 
さらに 4 を掛けた結果が、Base64 の総サイズとなります。
 
■バイナリから Base64 にエンコードする
 
バイナリの 0 番目から順番に 6 bit ずつデータを取り出します。
 
得られた値は、変換テーブルを使って文字に変換します。
 
バイナリ 3 バイトごとに、4 文字分のテキストが発生する事になります。
 
111111 | 112222 | 222233 | 333333
 
バイナリが最後尾に到達した場合、残りは 0 で埋めます。
 
最後に、バイナリの総サイズを 3 で割ります。
 
余りが 1 だった場合、Base64 の最後尾に、等号『 = 』を 2 つ追加します。
 
余りが 2 だった場合、Base64 の最後尾に、等号『 = 』を 1 つ追加します。
 

■Base64 からバイナリにデコードする

 
■バイナリの総サイズを計算する
 
まず、Base64 のサイズを 4 で割ります。
 
もし余りが発生する場合、Base64 は異常なデータです。
 
次に、Base64 の最後尾に、等号『 = 』が連続して存在するか調べます。
 
最大で 2 個存在します。
 
バイナリの総サイズは、『 ((Base64 のサイズ) / 4 * 3) - (等号の数) 』 です。
 
■Base64 からバイナリにデコードする
 
Base64 の 0 番目から順番に文字を取り出します。
 
得られた文字は、変換テーブルを使って、6 bit の値に変換します。
 
バイナリを 0 番目から順番に 6 bit ずつ、上位から埋めていきます。
 
Base64 の 4 文字ごとに、3 バイトのバイナリが発生する事になります
 
11111122 | 22223333 | 33444444
 
バイナリが最後尾まで埋まった時点で完了です。
 
Base64 側は、等号『 = 』分が余ります。
 


 

Base64 と「バイナリデータ文字列」の相互変換

 
 


■「バイナリデータの文字列」について


バイナリデータの文字列とは、0 ~ 255 までの文字コードのみで構成されている文字列です。
 
1文字で1バイトを表現します。
 
文字列の途中に、『 NUL (0x00) 』などの制御文字の混入が可能な、ECMAScript ならではの文字列となります。
 
JavaScript でバイナリを取り扱う仕組みが無かった時代 (NN4) に生まれた API ですが、HTML5 にて標準化されました。
 
HTML5 世代では、ArrayBuffer クラスを使って、バイナリを取り扱います。
 

■「バイナリデータの文字列」から「Base64 文字列」にエンコード


バイナリデータの文字列から、Base64 文字列に変換するには、btoa() メソッドを使用します。
 
「Binary (String)」 to 「ASCII (Base64)」 の略のようです。
 
引数に、0 ~ 255 までの文字コードのみで構成されている文字列を指定します。
 
違反している場合、例外エラーが発生します。
 
このメソッドは、Internet Explorer 9 以前では未対応です。
 
任意の文字コードを指定して、該当するユニコード文字を得るには、String.fromCharCode() メソッドを使用します。
 
別途、エスケープ関数などを駆使すれば、すべての文字情報を、0 ~ 255 の範囲に収める事ができます。
 
Window.btoa( "バイナリデータの文字列" ) :String
第01引数 String0 ~ 255 までの文字コードのみで構成された、バイナリデータの文字列を指定する。違反している場合、例外エラーが発生する。
戻り値 StringBase64 文字列が得られる。
 
■「バイナリデータの文字列」から「Base64」にエンコードする関数

引数に、0 ~ 255 までの文字コードのみで構成されているバイナリデータの文字列を指定します。
 
不正なデータである場合、null 値が得られます。
 
Internet Explorer 6 以降でも動作します。
 
バイナリデータの文字列から Base64 文字列に変換する関数

// ------------------------------------------------------------
// バイナリデータの文字列から Base64 文字列に変換する関数 (同期実行)
// ------------------------------------------------------------
function Base64_From_StringOfBinaryData(binary){
	var dic = [
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
	];
	var base64 = "";
	var num = binary.length;
	var n = 0;
	var b = 0;

	var i = 0;
	while(i < num){
		b = binary.charCodeAt(i);
		if(b > 0xff) return null;
		base64 += dic[(b >> 2)];
		n = (b & 0x03) << 4;
		i ++;
		if(i >= num) break;

		b = binary.charCodeAt(i);
		if(b > 0xff) return null;
		base64 += dic[n | (b >> 4)];
		n = (b & 0x0f) << 2;
		i ++;
		if(i >= num) break;

		b = binary.charCodeAt(i);
		if(b > 0xff) return null;
		base64 += dic[n | (b >> 6)];
		base64 += dic[(b & 0x3f)];
		i ++;
	}

	var m = num % 3;
	if(m){
		base64 += dic[n];
	}
	if(m == 1){
		base64 += "==";
	}else if(m == 2){
		base64 += "=";
	}
	return base64;
}

// ------------------------------------------------------------
// バイナリデータの文字列から Base64 文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_From_StringOfBinaryData_Async(binary,callback,increment){
	var dic = [
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
	];
	var base64 = "";
	var num = binary.length;
	var n = 0;
	var b = 0;

	if(increment === undefined){
		increment = 10240;
	}

	var i = 0;
	var j = 0;
	function f(){
		while(i < num){
			b = binary.charCodeAt(i);
			if(b > 0xff){ callback(null); return; }
			base64 += dic[(b >> 2)];
			n = (b & 0x03) << 4;
			i ++;
			if(i >= num) break;

			b = binary.charCodeAt(i);
			if(b > 0xff){ callback(null); return; }
			base64 += dic[n | (b >> 4)];
			n = (b & 0x0f) << 2;
			i ++;
			if(i >= num) break;

			b = binary.charCodeAt(i);
			if(b > 0xff){ callback(null); return; }
			base64 += dic[n | (b >> 6)];
			base64 += dic[(b & 0x3f)];
			i ++;

			j += 3;
			if(j > increment){
				j = 0;
				setTimeout(f,1);
				return;
			}
		}

		var m = num % 3;
		if(m){
			base64 += dic[n];
		}
		if(m == 1){
			base64 += "==";
		}else if(m == 2){
			base64 += "=";
		}
		callback(base64);
	}

	setTimeout(f,1);
}
 

■「Base64 文字列」から「バイナリデータの文字列」にデコード


Base64 文字列から、バイナリデータの文字列に変換するには、atob() メソッドを使用します。
 
「ASCII (Base64)」 to 「Binary (String)」 の略のようです。
 
このメソッドは、Internet Explorer 9 以前では未対応です。
 
バイナリデータの文字列が得られます。
 
実際のバイト値を得るには、さらに String.charCodeAt() メソッドを使用します。
 
Window.atob( "Base64 文字列" ) :String
第01引数 StringBase64 文字列を指定する。
戻り値 Stringバイナリデータの文字列が得られる。
 
■「Base64 文字列」から「バイナリデータの文字列」にデコードする関数

引数に、Base64 文字列を指定します。
 
不正なデータである場合、null 値が得られます。
 
Internet Explorer 6 以降でも動作します。
 
Base64 文字列からバイナリデータの文字列に変換する関数

// ------------------------------------------------------------
// Base64 文字列からバイナリデータの文字列に変換する関数 (同期実行)
// ------------------------------------------------------------
function Base64_To_StringOfBinaryData(base64){
	var dic = new Object();
	dic[0x41]= 0; dic[0x42]= 1; dic[0x43]= 2; dic[0x44]= 3; dic[0x45]= 4; dic[0x46]= 5; dic[0x47]= 6; dic[0x48]= 7; dic[0x49]= 8; dic[0x4a]= 9; dic[0x4b]=10; dic[0x4c]=11; dic[0x4d]=12; dic[0x4e]=13; dic[0x4f]=14; dic[0x50]=15;
	dic[0x51]=16; dic[0x52]=17; dic[0x53]=18; dic[0x54]=19; dic[0x55]=20; dic[0x56]=21; dic[0x57]=22; dic[0x58]=23; dic[0x59]=24; dic[0x5a]=25; dic[0x61]=26; dic[0x62]=27; dic[0x63]=28; dic[0x64]=29; dic[0x65]=30; dic[0x66]=31;
	dic[0x67]=32; dic[0x68]=33; dic[0x69]=34; dic[0x6a]=35; dic[0x6b]=36; dic[0x6c]=37; dic[0x6d]=38; dic[0x6e]=39; dic[0x6f]=40; dic[0x70]=41; dic[0x71]=42; dic[0x72]=43; dic[0x73]=44; dic[0x74]=45; dic[0x75]=46; dic[0x76]=47;
	dic[0x77]=48; dic[0x78]=49; dic[0x79]=50; dic[0x7a]=51; dic[0x30]=52; dic[0x31]=53; dic[0x32]=54; dic[0x33]=55; dic[0x34]=56; dic[0x35]=57; dic[0x36]=58; dic[0x37]=59; dic[0x38]=60; dic[0x39]=61; dic[0x2b]=62; dic[0x2f]=63;
	var binary = "";
	var num = base64.length;
	var n = 0;
	var b = 0;
	var e;

	if(!num) return binary;
	if(num < 4) return null;
	if(num % 4) return null;

	e = num / 4 * 3;
	if(base64.charAt(num - 1) == '=') e -= 1;
	if(base64.charAt(num - 2) == '=') e -= 1;

	var i = 0;
	var p = 0;
	while(p < e){
		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		n = (b << 2);
		i ++;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		binary += String.fromCharCode(n | ((b >> 4) & 0x3));
		n = (b & 0x0f) << 4;
		i ++;
		p ++;
		if(p >= e) break;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		binary += String.fromCharCode(n | ((b >> 2) & 0xf));
		n = (b & 0x03) << 6;
		i ++;
		p ++;
		if(p >= e) break;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		binary += String.fromCharCode(n | b);
		i ++;
		p ++;
	}
	return binary;
}

// ------------------------------------------------------------
// Base64 文字列からバイナリデータの文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_To_StringOfBinaryData_Async(base64,callback,increment){
	var dic = new Object();
	dic[0x41]= 0; dic[0x42]= 1; dic[0x43]= 2; dic[0x44]= 3; dic[0x45]= 4; dic[0x46]= 5; dic[0x47]= 6; dic[0x48]= 7; dic[0x49]= 8; dic[0x4a]= 9; dic[0x4b]=10; dic[0x4c]=11; dic[0x4d]=12; dic[0x4e]=13; dic[0x4f]=14; dic[0x50]=15;
	dic[0x51]=16; dic[0x52]=17; dic[0x53]=18; dic[0x54]=19; dic[0x55]=20; dic[0x56]=21; dic[0x57]=22; dic[0x58]=23; dic[0x59]=24; dic[0x5a]=25; dic[0x61]=26; dic[0x62]=27; dic[0x63]=28; dic[0x64]=29; dic[0x65]=30; dic[0x66]=31;
	dic[0x67]=32; dic[0x68]=33; dic[0x69]=34; dic[0x6a]=35; dic[0x6b]=36; dic[0x6c]=37; dic[0x6d]=38; dic[0x6e]=39; dic[0x6f]=40; dic[0x70]=41; dic[0x71]=42; dic[0x72]=43; dic[0x73]=44; dic[0x74]=45; dic[0x75]=46; dic[0x76]=47;
	dic[0x77]=48; dic[0x78]=49; dic[0x79]=50; dic[0x7a]=51; dic[0x30]=52; dic[0x31]=53; dic[0x32]=54; dic[0x33]=55; dic[0x34]=56; dic[0x35]=57; dic[0x36]=58; dic[0x37]=59; dic[0x38]=60; dic[0x39]=61; dic[0x2b]=62; dic[0x2f]=63;
	var binary = "";
	var num = base64.length;
	var n = 0;
	var b = 0;
	var e;

	if(increment === undefined){
		increment = 10240;
	}

	if(!num){ callback(binary); return; }
	if(num < 4){ callback(null); return; }
	if(num % 4){ callback(null); return; }

	e = num / 4 * 3;
	if(base64.charAt(num - 1) == '=') e -= 1;
	if(base64.charAt(num - 2) == '=') e -= 1;

	var i = 0;
	var j = 0;
	var p = 0;
	function f(){
		while(p < e){
			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			n = (b << 2);
			i ++;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			binary += String.fromCharCode(n | ((b >> 4) & 0x3));
			n = (b & 0x0f) << 4;
			i ++;
			p ++;
			if(p >= e) break;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			binary += String.fromCharCode(n | ((b >> 2) & 0xf));
			n = (b & 0x03) << 6;
			i ++;
			p ++;
			if(p >= e) break;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			binary += String.fromCharCode(n | b);
			i ++;
			p ++;

			j += 4;
			if(j > increment){
				j = 0;
				setTimeout(f,1);
				return;
			}
		}
		callback(binary);
	}

	setTimeout(f,1);
}
 


 

Base64 と「x-user-defined 文字列」の相互変換

 
 


■「x-user-defined 文字列」について


x-user-defined は、バイナリを取り扱うための言語コードです。
 
U+0000(0)~U+007F(127)、U+F780(128)~U+F7FF(255) の文字コードのみで構成されています。
 
1文字で1バイトを表現します。
 
文字からバイト情報を得る場合、ユニコードで下位1バイトのみを参照します。
 

■「x-user-defined 文字列」から「Base64 文字列」にエンコード

 
■「x-user-defined 文字列」から「Base64」にエンコードする関数

引数に、x-user-defined 文字列を指定します。
 
バイナリ形式に変換後、Base64 文字列にエンコードします。
 
Internet Explorer 6 以降でも動作します。
 
x-user-defined 文字列から Base64 文字列に変換する関数

// ------------------------------------------------------------
// x-user-defined 文字列から Base64 文字列に変換する関数 (同期実行)
// ------------------------------------------------------------
function Base64_From_XUserDefined(x_user_defined){
	var dic = [
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
	];
	var base64 = "";
	var num = x_user_defined.length;
	var n = 0;
	var b = 0;

	var i = 0;
	while(i < num){
		b = x_user_defined.charCodeAt(i) & 0xff;
		base64 += dic[(b >> 2)];
		n = (b & 0x03) << 4;
		i ++;
		if(i >= num) break;

		b = x_user_defined.charCodeAt(i) & 0xff;
		base64 += dic[n | (b >> 4)];
		n = (b & 0x0f) << 2;
		i ++;
		if(i >= num) break;

		b = x_user_defined.charCodeAt(i) & 0xff;
		base64 += dic[n | (b >> 6)];
		base64 += dic[(b & 0x3f)];
		i ++;
	}

	var m = num % 3;
	if(m){
		base64 += dic[n];
	}
	if(m == 1){
		base64 += "==";
	}else if(m == 2){
		base64 += "=";
	}
	return base64;
}

// ------------------------------------------------------------
// x-user-defined 文字列から Base64 文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_From_XUserDefined_Async(x_user_defined,callback,increment){
	var dic = [
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
	];
	var base64 = "";
	var num = x_user_defined.length;
	var n = 0;
	var b = 0;

	if(increment === undefined){
		increment = 10240;
	}

	var i = 0;
	var j = 0;
	function f(){
		while(i < num){
			b = x_user_defined.charCodeAt(i) & 0xff;
			base64 += dic[(b >> 2)];
			n = (b & 0x03) << 4;
			i ++;
			if(i >= num) break;

			b = x_user_defined.charCodeAt(i) & 0xff;
			base64 += dic[n | (b >> 4)];
			n = (b & 0x0f) << 2;
			i ++;
			if(i >= num) break;

			b = x_user_defined.charCodeAt(i) & 0xff;
			base64 += dic[n | (b >> 6)];
			base64 += dic[(b & 0x3f)];
			i ++;

			j += 3;
			if(j > increment){
				j = 0;
				setTimeout(f,1);
				return;
			}
		}

		var m = num % 3;
		if(m){
			base64 += dic[n];
		}
		if(m == 1){
			base64 += "==";
		}else if(m == 2){
			base64 += "=";
		}
		callback(base64);
	}

	setTimeout(f,1);
}
 

■「Base64 文字列」から「x-user-defined 文字列」にデコード

 
■「Base64 文字列」から「x-user-defined 文字列」にデコードする関数

引数に、バイナリをエンコードした Base64 文字列を指定します。
 
不正なデータである場合、null 値が得られます。
 
Internet Explorer 6 以降でも動作します。
 
Base64 文字列からx-user-defined 文字列に変換する関数

// ------------------------------------------------------------
// Base64 文字列からx-user-defined 文字列に変換する関数 (同期実行)
// ------------------------------------------------------------
function Base64_To_XUserDefined(base64){
	var dic = new Object();
	dic[0x41]= 0; dic[0x42]= 1; dic[0x43]= 2; dic[0x44]= 3; dic[0x45]= 4; dic[0x46]= 5; dic[0x47]= 6; dic[0x48]= 7; dic[0x49]= 8; dic[0x4a]= 9; dic[0x4b]=10; dic[0x4c]=11; dic[0x4d]=12; dic[0x4e]=13; dic[0x4f]=14; dic[0x50]=15;
	dic[0x51]=16; dic[0x52]=17; dic[0x53]=18; dic[0x54]=19; dic[0x55]=20; dic[0x56]=21; dic[0x57]=22; dic[0x58]=23; dic[0x59]=24; dic[0x5a]=25; dic[0x61]=26; dic[0x62]=27; dic[0x63]=28; dic[0x64]=29; dic[0x65]=30; dic[0x66]=31;
	dic[0x67]=32; dic[0x68]=33; dic[0x69]=34; dic[0x6a]=35; dic[0x6b]=36; dic[0x6c]=37; dic[0x6d]=38; dic[0x6e]=39; dic[0x6f]=40; dic[0x70]=41; dic[0x71]=42; dic[0x72]=43; dic[0x73]=44; dic[0x74]=45; dic[0x75]=46; dic[0x76]=47;
	dic[0x77]=48; dic[0x78]=49; dic[0x79]=50; dic[0x7a]=51; dic[0x30]=52; dic[0x31]=53; dic[0x32]=54; dic[0x33]=55; dic[0x34]=56; dic[0x35]=57; dic[0x36]=58; dic[0x37]=59; dic[0x38]=60; dic[0x39]=61; dic[0x2b]=62; dic[0x2f]=63;
	var x_user_defined = "";
	var num = base64.length;
	var n = 0;
	var b = 0;
	var e;

	if(!num) return x_user_defined;
	if(num < 4) return null;
	if(num % 4) return null;

	e = num / 4 * 3;
	if(base64.charAt(num - 1) == '=') e -= 1;
	if(base64.charAt(num - 2) == '=') e -= 1;

	var i = 0;
	var p = 0;
	while(p < e){
		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		n = (b << 2);
		i ++;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		n |= (b >> 4) & 0x3;
		x_user_defined += String.fromCharCode((n < 0x80) ? (n) : (0xf700 | n));
		n = (b & 0x0f) << 4;
		i ++;
		p ++;
		if(p >= e) break;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		n |= (b >> 2) & 0xf;
		x_user_defined += String.fromCharCode((n < 0x80) ? (n) : (0xf700 | n));
		n = (b & 0x03) << 6;
		i ++;
		p ++;
		if(p >= e) break;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		n |= b;
		x_user_defined += String.fromCharCode((n < 0x80) ? (n) : (0xf700 | n));
		i ++;
		p ++;
	}
	return x_user_defined;
}

// ------------------------------------------------------------
// Base64 文字列からx-user-defined 文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_To_XUserDefined_Async(base64,callback,increment){
	var dic = new Object();
	dic[0x41]= 0; dic[0x42]= 1; dic[0x43]= 2; dic[0x44]= 3; dic[0x45]= 4; dic[0x46]= 5; dic[0x47]= 6; dic[0x48]= 7; dic[0x49]= 8; dic[0x4a]= 9; dic[0x4b]=10; dic[0x4c]=11; dic[0x4d]=12; dic[0x4e]=13; dic[0x4f]=14; dic[0x50]=15;
	dic[0x51]=16; dic[0x52]=17; dic[0x53]=18; dic[0x54]=19; dic[0x55]=20; dic[0x56]=21; dic[0x57]=22; dic[0x58]=23; dic[0x59]=24; dic[0x5a]=25; dic[0x61]=26; dic[0x62]=27; dic[0x63]=28; dic[0x64]=29; dic[0x65]=30; dic[0x66]=31;
	dic[0x67]=32; dic[0x68]=33; dic[0x69]=34; dic[0x6a]=35; dic[0x6b]=36; dic[0x6c]=37; dic[0x6d]=38; dic[0x6e]=39; dic[0x6f]=40; dic[0x70]=41; dic[0x71]=42; dic[0x72]=43; dic[0x73]=44; dic[0x74]=45; dic[0x75]=46; dic[0x76]=47;
	dic[0x77]=48; dic[0x78]=49; dic[0x79]=50; dic[0x7a]=51; dic[0x30]=52; dic[0x31]=53; dic[0x32]=54; dic[0x33]=55; dic[0x34]=56; dic[0x35]=57; dic[0x36]=58; dic[0x37]=59; dic[0x38]=60; dic[0x39]=61; dic[0x2b]=62; dic[0x2f]=63;
	var x_user_defined = "";
	var num = base64.length;
	var n = 0;
	var b = 0;
	var e;

	if(increment === undefined){
		increment = 10240;
	}

	if(!num){ callback(x_user_defined); return; }
	if(num < 4){ callback(null); return; }
	if(num % 4){ callback(null); return; }

	e = num / 4 * 3;
	if(base64.charAt(num - 1) == '=') e -= 1;
	if(base64.charAt(num - 2) == '=') e -= 1;

	var i = 0;
	var j = 0;
	var p = 0;
	function f(){
		while(p < e){
			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			n = (b << 2);
			i ++;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			n |= (b >> 4) & 0x3;
			x_user_defined += String.fromCharCode((n < 0x80) ? (n) : (0xf700 | n));
			n = (b & 0x0f) << 4;
			i ++;
			p ++;
			if(p >= e) break;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			n |= (b >> 2) & 0xf;
			x_user_defined += String.fromCharCode((n < 0x80) ? (n) : (0xf700 | n));
			n = (b & 0x03) << 6;
			i ++;
			p ++;
			if(p >= e) break;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			n |= b;
			x_user_defined += String.fromCharCode((n < 0x80) ? (n) : (0xf700 | n));
			i ++;
			p ++;

			j += 4;
			if(j > increment){
				j = 0;
				setTimeout(f,1);
				return;
			}
		}
		callback(x_user_defined);
	}

	setTimeout(f,1);
}
 


 

Base64 と「ArrayBuffer」の相互変換

 
 


■「ArrayBuffer」について


ArrayBuffer クラスを使用すると、バイナリデータを取り扱う事ができます。
 
詳しくは、こちらで解説しています。
 

■「ArrayBuffer」から「Base64 文字列」にエンコード

 
■「ArrayBuffer」から「Base64」にエンコードする関数

引数に、ArrayBuffer オブジェクトを指定します。
 
ArrayBuffer から Base64 文字列に変換する関数

// ------------------------------------------------------------
// ArrayBuffer から Base64 文字列に変換する関数 (同期実行)
// ------------------------------------------------------------
function Base64_From_ArrayBuffer(ary_buffer){
	var dic = [
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
	];
	var base64 = "";
	var ary_u8 = new Uint8Array( ary_buffer );
	var num = ary_u8.length;
	var n = 0;
	var b = 0;

	var i = 0;
	while(i < num){
		b = ary_u8[i];
		base64 += dic[(b >> 2)];
		n = (b & 0x03) << 4;
		i ++;
		if(i >= num) break;

		b = ary_u8[i];
		base64 += dic[n | (b >> 4)];
		n = (b & 0x0f) << 2;
		i ++;
		if(i >= num) break;

		b = ary_u8[i];
		base64 += dic[n | (b >> 6)];
		base64 += dic[(b & 0x3f)];
		i ++;
	}

	var m = num % 3;
	if(m){
		base64 += dic[n];
	}
	if(m == 1){
		base64 += "==";
	}else if(m == 2){
		base64 += "=";
	}
	return base64;
}

// ------------------------------------------------------------
// ArrayBuffer から Base64 文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_From_ArrayBuffer_Async(ary_buffer,callback,increment){
	var dic = [
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
	];
	var base64 = "";
	var ary_u8 = new Uint8Array( ary_buffer );
	var num = ary_u8.length;
	var n = 0;
	var b = 0;

	if(increment === undefined){
		increment = 10240;
	}

	var i = 0;
	var j = 0;
	function f(){
		while(i < num){
			b = ary_u8[i];
			base64 += dic[(b >> 2)];
			n = (b & 0x03) << 4;
			i ++;
			if(i >= num) break;

			b = ary_u8[i];
			base64 += dic[n | (b >> 4)];
			n = (b & 0x0f) << 2;
			i ++;
			if(i >= num) break;

			b = ary_u8[i];
			base64 += dic[n | (b >> 6)];
			base64 += dic[(b & 0x3f)];
			i ++;

			j += 3;
			if(j > increment){
				j = 0;
				setTimeout(f,1);
				return;
			}
		}

		var m = num % 3;
		if(m){
			base64 += dic[n];
		}
		if(m == 1){
			base64 += "==";
		}else if(m == 2){
			base64 += "=";
		}
		callback(base64);
	}

	setTimeout(f,1);
}
 

■「Base64 文字列」から「ArrayBuffer」にデコード

 
■「Base64 文字列」から「ArrayBuffer」にデコードする関数

引数に、Base64 文字列を指定します。
 
不正なデータである場合、null 値が得られます。
 
Base64 文字列からArrayBufferに変換する関数

// ------------------------------------------------------------
// Base64 文字列から ArrayBuffer に変換する関数 (同期実行)
// ------------------------------------------------------------
function Base64_To_ArrayBuffer(base64){
	var dic = new Object();
	dic[0x41]= 0; dic[0x42]= 1; dic[0x43]= 2; dic[0x44]= 3; dic[0x45]= 4; dic[0x46]= 5; dic[0x47]= 6; dic[0x48]= 7; dic[0x49]= 8; dic[0x4a]= 9; dic[0x4b]=10; dic[0x4c]=11; dic[0x4d]=12; dic[0x4e]=13; dic[0x4f]=14; dic[0x50]=15;
	dic[0x51]=16; dic[0x52]=17; dic[0x53]=18; dic[0x54]=19; dic[0x55]=20; dic[0x56]=21; dic[0x57]=22; dic[0x58]=23; dic[0x59]=24; dic[0x5a]=25; dic[0x61]=26; dic[0x62]=27; dic[0x63]=28; dic[0x64]=29; dic[0x65]=30; dic[0x66]=31;
	dic[0x67]=32; dic[0x68]=33; dic[0x69]=34; dic[0x6a]=35; dic[0x6b]=36; dic[0x6c]=37; dic[0x6d]=38; dic[0x6e]=39; dic[0x6f]=40; dic[0x70]=41; dic[0x71]=42; dic[0x72]=43; dic[0x73]=44; dic[0x74]=45; dic[0x75]=46; dic[0x76]=47;
	dic[0x77]=48; dic[0x78]=49; dic[0x79]=50; dic[0x7a]=51; dic[0x30]=52; dic[0x31]=53; dic[0x32]=54; dic[0x33]=55; dic[0x34]=56; dic[0x35]=57; dic[0x36]=58; dic[0x37]=59; dic[0x38]=60; dic[0x39]=61; dic[0x2b]=62; dic[0x2f]=63;
	var num = base64.length;
	var n = 0;
	var b = 0;
	var e;

	if(!num) return (new ArrayBuffer(0));
	if(num < 4) return null;
	if(num % 4) return null;

	e = num / 4 * 3;
	if(base64.charAt(num - 1) == '=') e -= 1;
	if(base64.charAt(num - 2) == '=') e -= 1;

	var ary_buffer = new ArrayBuffer( e );
	var ary_u8 = new Uint8Array( ary_buffer );
	var i = 0;
	var p = 0;
	while(p < e){
		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		n = (b << 2);
		i ++;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		ary_u8[p] = n | ((b >> 4) & 0x3);
		n = (b & 0x0f) << 4;
		i ++;
		p ++;
		if(p >= e) break;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		ary_u8[p] = n | ((b >> 2) & 0xf);
		n = (b & 0x03) << 6;
		i ++;
		p ++;
		if(p >= e) break;

		b = dic[base64.charCodeAt(i)];
		if(b === undefined) return null;
		ary_u8[p] = n | b;
		i ++;
		p ++;
	}
	return ary_buffer;
}

// ------------------------------------------------------------
// Base64 文字列から ArrayBuffer に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_To_ArrayBuffer_Async(base64,callback,increment){
	var dic = new Object();
	dic[0x41]= 0; dic[0x42]= 1; dic[0x43]= 2; dic[0x44]= 3; dic[0x45]= 4; dic[0x46]= 5; dic[0x47]= 6; dic[0x48]= 7; dic[0x49]= 8; dic[0x4a]= 9; dic[0x4b]=10; dic[0x4c]=11; dic[0x4d]=12; dic[0x4e]=13; dic[0x4f]=14; dic[0x50]=15;
	dic[0x51]=16; dic[0x52]=17; dic[0x53]=18; dic[0x54]=19; dic[0x55]=20; dic[0x56]=21; dic[0x57]=22; dic[0x58]=23; dic[0x59]=24; dic[0x5a]=25; dic[0x61]=26; dic[0x62]=27; dic[0x63]=28; dic[0x64]=29; dic[0x65]=30; dic[0x66]=31;
	dic[0x67]=32; dic[0x68]=33; dic[0x69]=34; dic[0x6a]=35; dic[0x6b]=36; dic[0x6c]=37; dic[0x6d]=38; dic[0x6e]=39; dic[0x6f]=40; dic[0x70]=41; dic[0x71]=42; dic[0x72]=43; dic[0x73]=44; dic[0x74]=45; dic[0x75]=46; dic[0x76]=47;
	dic[0x77]=48; dic[0x78]=49; dic[0x79]=50; dic[0x7a]=51; dic[0x30]=52; dic[0x31]=53; dic[0x32]=54; dic[0x33]=55; dic[0x34]=56; dic[0x35]=57; dic[0x36]=58; dic[0x37]=59; dic[0x38]=60; dic[0x39]=61; dic[0x2b]=62; dic[0x2f]=63;
	var num = base64.length;
	var n = 0;
	var b = 0;
	var e;

	if(increment === undefined){
		increment = 10240;
	}

	if(!num){ callback(new ArrayBuffer(0)); return; }
	if(num < 4){ callback(null); return; }
	if(num % 4){ callback(null); return; }

	e = num / 4 * 3;
	if(base64.charAt(num - 1) == '=') e -= 1;
	if(base64.charAt(num - 2) == '=') e -= 1;

	var ary_buffer = new ArrayBuffer( e );
	var ary_u8 = new Uint8Array( ary_buffer );
	var i = 0;
	var j = 0;
	var p = 0;
	function f(){
		while(p < e){
			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			n = (b << 2);
			i ++;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			ary_u8[p] = n | ((b >> 4) & 0x3);
			n = (b & 0x0f) << 4;
			i ++;
			p ++;
			if(p >= e) break;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			ary_u8[p] = n | ((b >> 2) & 0xf);
			n = (b & 0x03) << 6;
			i ++;
			p ++;
			if(p >= e) break;

			b = dic[base64.charCodeAt(i)];
			if(b === undefined){ callback(null); return; }
			ary_u8[p] = n | b;
			i ++;
			p ++;

			j += 4;
			if(j > increment){
				j = 0;
				setTimeout(f,1);
				return;
			}
		}
		callback(ary_buffer);
	}

	setTimeout(f,1);
}