[5] [DFN[Base64]] は、[[オクテット列]]を64種類の[[英数字]]などに転写する[[符号化方式]]の一種です。 (一般に [Q[base 64]] は[Q[64進数]]を意味します。特に大文字で [Q[Base64]] と書いた場合や、インターネットで言われる場合には、 [[MIME]] の Base64 を指します。) * 符号化方式 [27] オクテット値3つ (8ビット×3 = 24ビット) を4文字 (6ビット×4) で表現します。ですからデータ量は3分の4倍、33%増加になります。 64文字 (と、特殊用途に使われる [CODE(char)[=]]) は、 [[ISO/IEC 646の版]]で全て共通に存在し、しかも [[EBCDIC]] の全ての版で使える文字から選ばれたそうです。 [PRE[ Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y ]PRE] [28] Base64 は6ビット単位になりますが、オクテット列の長さと必ずしも 一致する (6と8の公倍数の長さになる) とは限らないので、 [CODE(char)[=]] で埋めて調節します。この結果、 Base64 data は必ず 4の整数倍の長さになります。 [24] Base64'ed data は、 一行辺り76文字以下でなければなりません。 ([[電子メイル]]/[[MIME]] の制限に由来。) 区切りの改行文字列 [CODE(char)[CRLF]] は、復号の時には無視されます。 (これ以外でも、上の表に無い文字が現れたら、無視して処理を続けます。) [30] UmFyIRoHAFK3cwAADQAAAHsAAADF4XQggi0AOgAAADoAAAACFWlHzumpbjAdMA0AIAAAAENEa2V5 LnR4dAABwAdUcnVlIEltYWdlIHZlcjcuMJP6lnuM6pTFDQoNCjJYUVFBLTZDMkZNLUFRN1FXLUtK WlpVLU5NRTJG7ER6AMDbAAAAAAAAAAAAAgAAAAB7njYxHTACAAAAAABBVgkAQ0RrZXkucmFyAAAH AFZpcnR1YWwAAD1gLZ3sLHznsQOOODQ9MD2jAksFFIPjRmNYZGjzAtJofh8fvvmvGZo56MP0EhIv QmvIfnM0yKSXRkrPQFu+IJmOX7UFLqRV17PwBmiJOADp9VlKVrLXY529IfzfR9BkPWBW5KYGZrl8 n4gw9tFlBpLDZFyCYDrVRHrXae23TzMxRmxnvmpiXsKr1WOnxvs3str2bjw3Ssvu5tQCUVx7njYx xD17AEAHAA== ([[名無しさん]] [WEAK[2004-12-23 02:01:42 +00:00]]) [32] 11 ([[名無しさん]] [WEAK[2005-02-19 08:01:06 +00:00]]) [[#comment]] * 仕様 [25] Base64 は、最初 [[PEM]] ([[RFC 1421]] ) で規定されましたが、後に [[MIME]] ([[RFC 1341]] , [[RFC 1521]] , [[RFC 2045]] ) で採用され、広く普及するに至りました。 [15] その後、 Base64 を規定する新しい RFC, [[RFC 3548]] がでました。 [6] PEM 以来の Base64 の定義を採用する仕様: - [[PEM]] 署名 - [[MIME]] [CODE(MIME)[Base64]] [[転送符号化]] - [CODE(MIME)[[[x-gzip64]]]] 転送符号化 - [[PGP/MIME]] 署名 - MIME [CODE(MIME)[[[Content-MD5]]:]] 欄 - [[822]] [CODE(822)[[[Face]]:]] 欄 - MIME [CODE(ABNF)[[[encoded-word]]]] [CODE(MIME)[B]] 符号化 - [CODE(URI)[[[data]]:]] [[URI]] [[scheme]] - [[uuencode]] 風表現 >>3 [[#comment]] * uuencode 風表現 [3] [[MIME]] 以外の場面でファイルを貼り付けるのに、 [[uuencode]] みたいな書き方をすることがあるみたい。 例1: [PRE[ begin-base64 644 base64ed.data [INS[... base64 stream ...]] ==== ]PRE] [26] 例2: [PRE[ begin-base64 644 code.tgz [INS[... base64 stream ...]] = ]PRE] [[#comment]] * 変種 [23] MIME Base64 と似ながら少しずつ異なる変種がいろいろ知られています。 ** 詰め文字の省略 [1] データ長がある程度決まっている場合は、 [CODE(char)[=]] padding が無駄であることがあります。この場合で、 [CODE(char)[=]] padding を省略すると規定しているものがあります。 [2] 必ず[[8ビット・バイト]]を使用するものは、 [CODE(char)[=]] padding の代わりに、元のデータの後に任意個の [CODE[0x00]] が並んでいる としても解釈上影響がないことがあります。そういうものがあります。 - [[UTF-7]] の Base64 は、必ず16ビット単位のデータを扱うので、 最後の詰め文字を省略すると規定されています。 - [29][[Norton AntiSpam]] は [CODE(ABNF)[[[encoded-word]]]] の最後の [CODE(MIME)[=]] を省くそうです。 [SRC[mew-dist 25264]] もちろんこの実装は MIME 違反です。 [[#comment]] ** 斜線の代替文字 [22] MIME の Base64 字母には [CODE(char)[/]] が含まれますが、 色々なシステムで階層の区切り文字として使われているので、 あまり嬉しくないことがあります。 [7] [[IMAP]] の修正 [[UTF-7]] では、 >>2 の修正に加えて、 [CODE(char)[/]] の代わりに [CODE(char)[,]] が使われています。 [9] [CODE(URI)[[[urn:urn-5]]]] [[URN]] [[名前空間]]で使っている Base64 変種は、 [CODE(char)[/]] の代わりに [CODE(char)[-]] を使います。 (URN では [CODE(URI)[/]] が使えないため。) また、詰め文字は使いません。 (''Namespace ID: urn-5'' ) [16] [[RFC 3548]] 曰く、 MIME Base64 ではファイル名や [[URI]] で安全ではないので、 [CODE(char)[/]] の代わりに [CODE(char)[~]] を使う提案があったそうです。しかし [CODE(char)[~]] もやはりファイル・システムや URI で安全とは言えません。 [17] そこで RFC 3548 はファイル名や URI で安全な代替 Base64 字母として、 [CODE(char)[+]] と [CODE(char)[/]] に代えて [CODE(char)[-]] と [CODE(char)[_]] を使うものを規定しています。それでも [CODE(char)[=]] が padding に使われてるので、まだ完全に URI で安全とは言えません。 [CODE(char)[-]] が先頭に来る可能性があるので [[Un|x]] で安全でない虞もあります。 [18] [[M$XML]] は [CODE(char)[/]] の代わりに [CODE(char)[*]] を使っていたそうです。最近の版では両方認識するそうです。 [[#comment]] ** memo [14] 変種ではありませんが、 [[MIME]] の [CODE(MIME)[[[application/octet-stream]]]] では、[[オクテット]] (8[[ビット]]) 単位でないビット列も扱うことが出来ます。 そのような場合には全体長が8の倍数になるようにビット [CODE[0]] を詰め、 詰めた数を引数でメモっておきます。 [[#comment]] * 実装 [4] [[Perl]] なら、 [CODE(perl)[[[MIME::Base64]]]] を使うのが気楽かと。 Perl 5.7.3 以降では標準で入っています。 但し、 >>1,>>2,>>7 のような変種には対応していません。 [8] [[uuencode]] も64進数であることを利用して、 uuencode で符号化した後に [CODE[[[tr]]]] を使うという方法が使われることもあります。 [[#comment]] * メモ [12] [[インターネット]]でのオクテット列の文字列転写法の[[デ・ファクト標準]]です。 [10] [[XML]] でバイナリを扱う時には Base64 を使うのが推奨されている (誰に?) そうです。 ([Q[XML は人間可読である]]のじゃなかったのか? って気もするが。) [11] >>10 実際のところ、 [[ISO/IEC 6479]] の[[制御シーケンス]]とかが混じったデータを使いたいという要求はある。 (それは XML の思想に反するという反発は強く、 XML 1.1 でも結局駄目になったけど。) [21] >>11 [[XML 1.1]] では結局[[文字参照]]なら OK ([CODE(char)[[[U+0000]]]] 以外。) になりましたね。 [13] >>11 でも、せめて [CODE(char)[[ABBR[[[FF]]] [FORM FEED]]]] くらい使いたい気はする。 (実質 [[Un*x]] でしか使えない環境依存だから入れたくないのかもしれんが。) [31] UmFyIRoHAFK3cwAADQAAAHsAAADF4XQggi0AOgAAADoAAAACFWlHzumpbjAdMA0AIAAAAENEa2V5 LnR4dAABwAdUcnVlIEltYWdlIHZlcjcuMJP6lnuM6pTFDQoNCjJYUVFBLTZDMkZNLUFRN1FXLUtK WlpVLU5NRTJG7ER6AMDbAAAAAAAAAAAAAgAAAAB7njYxHTACAAAAAABBVgkAQ0RrZXkucmFyAAAH AFZpcnR1YWwAAD1gLZ3sLHznsQOOODQ9MD2jAksFFIPjRmNYZGjzAtJofh8fvvmvGZo56MP0EhIv QmvIfnM0yKSXRkrPQFu+IJmOX7UFLqRV17PwBmiJOADp9VlKVrLXY529IfzfR9BkPWBW5KYGZrl8 n4gw9tFlBpLDZFyCYDrVRHrXae23TzMxRmxnvmpiXsKr1WOnxvs3str2bjw3Ssvu5tQCUVx7njYx xD17AEAHAA== ([[名無しさん]] [WEAK[2004-12-23 02:02:26 +00:00]])