[5] [DFN[Base64]] は、[[オクテット列]]を64種類の[[英数字]]などに転写する[[符号化方式]]の一種です。

[NOTE[
[135] 一般に [Q[base 64]] は[Q[64進数]]を意味します。特に[[大文字]]で [Q[Base64]]
と書いた場合や、[[インターネット]]で言われる場合には、 [[MIME]] の
[[Base64]] を指します。
]NOTE]

[196] 元々[[インターネットメール]]で[[バイナリー]]データを転送するための仕組みとして考案されました。
[[文字コード]]の異なる様々な[[システム]]間で転送される[[電子メール]]では、
任意の[[バイナリー]]データを転送することができなかったため、
限られた[[ASCII文字]]で[[符号化]]する手段が必要でした。
その後徐々に適用範囲が拡大され多種多様な目的で使われるようになりました。

[58] いくつかのバリエーションがあり、どれを使うべきなのか注意が必要です。

* 仕様書

[REFS[
- [115] [CITE@en[RFC 4648 - The Base16, Base32, and Base64 Data Encodings]] ([TIME[2018-01-28 17:12:45 +09:00]]) <https://tools.ietf.org/html/rfc4648#section-4>
- [830] [CITE@en[RFC 4648 - The Base16, Base32, and Base64 Data Encodings]] ([TIME[2012-04-15 07:19:30 +09:00]] 版) <https://tools.ietf.org/html/rfc4648#section-5>
- [86] '''[CITE@en[Infra Standard]] ([TIME[2017-08-17 16:48:46 +09:00]]) <https://infra.spec.whatwg.org/#forgiving-base64>'''
]REFS]

* 符号化方式の概要

[27]
オクテット値3つ (8ビット×3 = 24ビット) を4文字 (6ビット×4)
で表現します。ですからデータ量は3分の4倍、33%増加になります。

64文字 (と、特殊用途に使われる [CODE(char)[=]]) は、 
[[ISO/IEC 646の版]]で全て共通に存在し、しかも [[EBCDIC]] 
の全ての版で使える文字から選ばれたそうです。

[FIG(list)[ [116] [DFN[Table 1: The Base 64 Alphabet]]
[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]
]FIG]

[28]
Base64 は6ビット単位になりますが、オクテット列の長さと必ずしも
一致する (6と8の公倍数の長さになる) とは限らないので、
[CODE(char)[=]] で埋めて調節します。この結果、 Base64 data は必ず
4の整数倍の長さになります。

* 符号化

[136] '''[[Base64]] による[[符号化]]'''は、
任意の[[バイト列]]を [[Base64]] の [[ASCII文字列]]へと変換する処理です。

[89] [DFN[forgiving-base64 encode]] は、[[バイト列]][VAR[データ]]を次のようにします
[SRC[>>86]]。

[FIG(steps)[
= [90] [VAR[データ]]に [[RFC 4648]] 第4章 [[Base64]] を適用した結果を返します。
]FIG]

[117] [[RFC 4648]] 第4章 [[Base64]] は、
[[バイト列]][VAR[データ]]を次のようにします。

[FIG(steps)[
= [118] [VAR[塊]]を、[[空バイト列]]に設定します。
= [202] [VAR[結果]]を、[[空文字列]]に設定します。
= [119] [VAR[データ]]の各[[バイト]][VAR[バイト]]について、順に、
== [120] [VAR[塊]]の末尾に、[VAR[バイト]]を追加します。
== [122] [VAR[塊]]の[F[長さ]]が [N[3]] の場合、
=== [198] [VAR[ビット列0]]を、[VAR[塊]] [ [N[0]] ] の上位6ビットに設定します。
=== [199] [VAR[ビット列1]]を、[VAR[塊]] [ [N[0]] ] の下位2ビットを上位2ビット、
[VAR[塊]] [ [N[1]] ] の上位4ビットを下位4ビットとする[[ビット列]]に設定します。
=== [200] [VAR[ビット列2]]を、[VAR[塊]] [ [N[1]] ] の下位4ビットを上位4ビット、
[VAR[塊]] [ [N[2]] ] の上位2ビットを下位2ビットとする[[ビット列]]に設定します。
=== [201] [VAR[ビット列3]]を、[VAR[塊]] [ [N[2]] ] の下位6ビットに設定します。
=== [216] [VAR[結果]]の末尾に、
[VAR[ビット列0]]、[VAR[ビット列1]]、[VAR[ビット列2]]、[VAR[ビット列3]]のそれぞれが
[[The Base 64 Alphabet]] の第1列の値である行の第2列の値を順に追加します。
=== [215] [VAR[塊]]を、[[空バイト列]]に設定します。
= [204] [VAR[塊]]の[F[長さ]]が [N[2]] の場合、
== [205] [VAR[ビット列0]]を、[VAR[塊]] [ [N[0]] ] の上位6ビットに設定します。
== [206] [VAR[ビット列1]]を、[VAR[塊]] [ [N[0]] ] の下位2ビットを上位2ビット、
[VAR[塊]] [ [N[1]] ] の上位4ビットを下位4ビットとする[[ビット列]]に設定します。
== [207] [VAR[ビット列2]]を、[VAR[塊]] [ [N[1]] ] の下位4ビットを上位4ビット、
[N[0]] を下位2ビットとする[[ビット列]]に設定します。
== [208] [VAR[ビット列3]]を、 [I[(pad)]] に設定します。
== [217] [VAR[結果]]の末尾に、
[VAR[ビット列0]]、[VAR[ビット列1]]、[VAR[ビット列2]]、[VAR[ビット列3]]のそれぞれが
[[The Base 64 Alphabet]] の第1列の値である行の第2列の値を順に追加します。
= [209] [VAR[塊]]の[F[長さ]]が [N[1]] の場合、
== [210] [VAR[ビット列0]]を、[VAR[塊]] [ [N[0]] ] の上位6ビットに設定します。
== [211] [VAR[ビット列1]]を、[VAR[塊]] [ [N[0]] ] の下位2ビットを上位2ビット、
[N[0]] を下位4ビットとする[[ビット列]]に設定します。
== [212] [VAR[ビット列2]]を、 [I[(pad)]] に設定します。
== [213] [VAR[ビット列3]]を、 [I[(pad)]] に設定します。
== [203] [VAR[結果]]の末尾に、
[VAR[ビット列0]]、[VAR[ビット列1]]、[VAR[ビット列2]]、[VAR[ビット列3]]のそれぞれが
[[The Base 64 Alphabet]] の第1列の値である行の第2列の値を順に追加します。
= [214] [VAR[結果]]を返します。
]FIG]

-*-*-

[123] 次の文脈で用いられます。

[FIG(middle list)[ [124] [[forgiving-base64 encode]] の[[応用]]
- [CODE[atob]]
- [CODE[Sec-WebSocket-Key:]]
]FIG]

* 復号

[137] '''[[Base64]] による[[復号]]'''は、
[[Base64]] の [[ASCII文字列]]をその表す[[バイト列]]へと変換する処理です。

[91] [DFN[forgiving-base64 decode]] は、[[文字列]][VAR[データ]]を次のようにします
[SRC[>>86]]。

[FIG(steps)[
= [92] [VAR[データ]]から[[ASCII空白]]をすべて削除します。
= [93] [VAR[データ]]の[F[長さ]] [[%]] [N[4]] が [N[0]] の場合、
== [94] [VAR[データ]]の末尾が [CODE[==]] か [CODE[=]] なら、これを削除します。
= [95] [VAR[データ]]の[F[長さ]] [[%]] [N[4]] が [N[1]] の場合、
== [96] [[失敗]]を返し、ここで停止します。
= [97] [VAR[データ]]に [CODE[+]]、[CODE[/]]、[[ASCII英数字]]のいずれでもない[[符号位置]]が含まれる場合、
== [98] [[失敗]]を返し、ここで停止します。
= [99] [VAR[出力]]を、新しい[[空バイト列]]に設定します。
= [100] [VAR[バッファー]]を、新しい空[[ビット列]]に設定します。
= [101] [VAR[データ]]に含まれる[[符号位置]][VAR[符号位置]]について、順に、
== [102] [VAR[n]] を、[[RFC 4648]] [[Table 1: The Base 64 Alphabet]]
の第2列が[VAR[符号位置]]である[[行]]の第1列の値に設定します。
== [103] [VAR[バッファー]]の末尾に、[VAR[n]] と等しく6ビットで[[大エンディアン]]の[[ビット列]]を追加します。
== [104] [VAR[バッファー]]の[F[長さ]]が24ビットの場合、
=== [105] [VAR[バッファー]]を3桁の[[大エンディアン]][[8ビット整数]]と解釈したものを、
[VAR[出力]]の末尾に順に追加します。
=== [106] [VAR[バッファー]]を、空に設定します。
= [107] [VAR[バッファー]]の[F[長さ]]が12ビットの場合、
== [108] [VAR[バッファー]]の先頭8ビットを
1桁の[[大エンディアン]][[8ビット整数]]と解釈したものを、
[VAR[出力]]の末尾に順に追加します。
= [109] [VAR[バッファー]]の[F[長さ]]が18ビットの場合、
== [110] [VAR[バッファー]]の先頭16ビットを
2桁の[[大エンディアン]][[8ビット整数]]と解釈したものを、
[VAR[出力]]の末尾に順に追加します。
= [111] [VAR[出力]]を返します。
]FIG]

[125] 次の文脈で用いられます。

[FIG(middle list)[ [126] [[forgiving-base64 decode]] の[[応用]]
- [CODE[btoa]]
- [[[CODE[data:]] URL処理器]]
]FIG]

[225] [[仕様書]]上 [[forgiving-base64 decode]] は入力が[[文字列]]として定義されています。
[[[CODE[data:]] URL処理器]]では入力が[[バイト列]]となるため、
[[同型復号]]を通しています。

* Base64 の仕様書とバリエーション

[138] 「[[Base64]]」と呼ばれているものは、
注意して観察すると色々なバリエーションがあることがわかります。
[[Base64]] は有用で様々な用途に活用されてきたのですが、
その過程で[[仕様書]]の規定の部分を[[コピペ]]したり、
用途依存の細かい改変を加えたりされたため、
単一の定義と言えるものが存在しなくなってしまいました。

[23] どの[[仕様書]]の定義を参照するかという[[政治的]]な問題の他に、
技術的に様々な違いがありますが、
主として次のような観点で比較できます。

- [139] [[字母]]。[[ASCII英数字]]はそのまま使われることが多いですが、
それ以外の[[記号]]は差し替えられていることがあります。
- [31] [[詰め]]。末尾の余分なデータを表す「詰め文字」を必須とするもの、
省略可能とするもの、禁止しているものがあります。
- [140] [[空白]]・[[改行]]。[[行長]]を固定するもの、
制限するもの、[[改行]]を禁止するものがあります。
- [141] [[誤り処理]]。不正な入力が与えられたときの回復処理を規定するもの、
処理を中断することが求められるもの、
明確な規定がないものがあります。


** 電子メールの Base64

[145] [[Base64]] は最初に [[PEM]] で導入されました。
[[PEM]] は特別な名前を与えず、単に「printable encoding」 (印字可能符号化)
と呼んでいました。 [SRC[>>142, >>143, >>144]]

[146] [[字母]]や[[詰め]]については既に後の時代と同じ規定となっていました。
符号化後の最終行以外の各行は、64文字としなければならないとされていました。
誤り処理の明確な規定はありませんでした。

[147] [[字母]]は、当時使われていた [[ASCII]] や [[EBCDIC]] 
を[[文字コード]]とするシステムで問題なく扱えるものが選ばれていました。
行長制限は、[[SMTP]] の制約に由来するものでした。

[148] [[PEM]] の [[Base64]] は、あくまで [[PEM]] のプロトコルの一部を構成するもので、
汎用的な利用を想定したものではありませんでした。 [[Base64]] の[[字母]]に加え、 [[PEM]]
での利用上特別な意味を持った区切りの[[文字]] [CODE[*]] 
も[[字母]]の1つとして挙げられていました。

[166] 符号化の方法は規定されていましたが、復号の方法は明確には定められていませんでした。

[FIG(list middle)[ [157] [[PEM]] [[Base64]] の[[応用]]
- [[PEM]] [[署名]]
]FIG]

[REFS[
- [142] [CITE@en[RFC 989 - Privacy enhancement for Internet electronic mail: Part I: Message encipherment and authentication procedures]] ([TIME[2018-01-22 01:26:57 +09:00]]) <https://tools.ietf.org/html/rfc989#section-4.3>
- [143] [CITE@en[RFC 1040 - Privacy enhancement for Internet electronic mail: Part I: Message encipherment and authentication procedures]] ([TIME[2018-01-21 19:31:09 +09:00]]) <https://tools.ietf.org/html/rfc1040#section-4.3.2.4>
- [144] [CITE@en[RFC 1113 - Privacy enhancement for Internet electronic mail: Part I - message encipherment and authentication procedures]] ([TIME[2018-01-28 19:33:06 +09:00]]) <https://tools.ietf.org/html/rfc1113#section-4.3.2.4>
]REFS]

-*-*-

[25] [[MIME]] は、 [[PEM]] から派生して独自の [[Base64]] を規定しました 
[SRC[>>149, >>150, >>43]]。 [[Base64]] という名称はここで与えられました。

[151] 基本的には [[PEM]] と同内容ですが、いくつかの違いがありました。

[152] [[MIME]] では特別な意味を持たない [CODE[*]] は[[字母]]に含まれませんでした。

[153] 行長制限は、76文字[[以下]]とされました。

[154] [[字母]]以外は無視するべきことと定められ、
[[字母]]、[[改行]]、[[空白]]以外は誤りと考えられるため警告を出したり、
場合によっては拒絶するのもよいとされました。

[155] [[RFC 1521]] は [CODE[====]] のようなあり得ない[[詰め]]を無視することを定めていましたが、
改訂版の [[RFC 2045]] ではなぜか削除されました。

[156] このように [[PEM]] とは違って誤り処理が定められたことは注目に値しますが、
起こり得るすべての誤りケースをカバーできてはいませんでした。

[FIG(list middle)[ [158] [[MIME]] [[Base64]] の[[応用]]
- [[MIME]] [CODE(MIME)[Base64]] [[転送符号化]]
- [CODE(MIME)[[[x-gzip64]]]] 転送符号化
- [CODE(MIME)[[[Content-MD5]]:]] ヘッダー
- [CODE(822)[Face:]] ヘッダー
- MIME [CODE(ABNF)[[[encoded-word]]]] [CODE(MIME)[B]] 符号化
- [[uuencode]] 風表現 >>3
- [32] [CODE(ABNF)[[[instance-digest]]]]
([CODE(ABNF)[[[digest-algorithm]]]] が
[CODE(HTTP)[[[SHA]]]] または [CODE(HTTP)[[[MD5]]]] の時)
- [[Atom 0.3]] [CODE[mode=base64]] (→ [[RFC 2045]])
- [[OAuth 1.0]] [CODE[HMAC-SHA1]] (→ [[RFC 2045]])
- [[OAuth 1.0]] [CODE[RSA-SHA1]] (→ [[RFC 2045]])
]FIG]

[170] [CODE[Content-MD5:]] を定める [[RFC 1864]] は「base64」としか言っておらず、
どこで規定される何を指すのかは曖昧ですが、 [[MIME]] の追加機能ですから、
[[MIME]] の定義と解釈するのが自然でしょう。
[[ヘッダー値]]として使うため[[改行]]を自由には挿入できないはずですが、
符号化される値は十分短いため、実際には問題とはなりません。

[281] 
[[RFC 2065]]
は
[[RFC 1521]]
から
[[Base64]]
部分を[[コピペ]]して組み込んでいました。
[SRC[>>280]]

[827] [[基本認証]]の [[credentials]] では [[MIME]] の [[RFC 1521]] や [[RFC 2045]] の 
[[Base64]] から行長制限を撤廃したものと規定されていました [SRC[>>826, >>183, >>828]]。
厳密に読めば制限が撤廃されたのは良いとして、[[改行]]が認められるのかは不明でした。
この点は後の改訂で明確化されました (>>185)。

[171] [CODE[data:]] を定める [[RFC 2397]] は「base64」としか言っておらず、
どこで規定される何を指すのかは曖昧ですが、[[参考文献]]として示された
[[MIME]] の [[RFC 2045]] だけが文脈から推測できる候補でした。
しかし行長制限の扱いと [[URL]] としての構文の矛盾など、
[[著者]]の意図を断言するのは難しい状態でした。
(出版から20年後にようやく [CITE[Fetch Standard]] により明確化されることになります。)

[224] [[OAuth 1.0]] の [CODE[HMAC-SHA1]] や [CODE[RSA-SHA1]]
は [[RFC 2045]] の [[Base64]] を採用していました。
符号化される値は十分短いため、
行長制限に達することはありません。

[REFS[
- [149] [CITE@en[RFC 1341 - MIME (Multipurpose Internet Mail Extensions): Mechanisms for Specifying and Describing the Format of Internet Message Bodies]] ([TIME[2018-01-21 20:29:24 +09:00]]) <https://tools.ietf.org/html/rfc1341#page-17>
- [150] [CITE@en[RFC 1521 - MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies]] ([TIME[2018-01-21 18:17:10 +09:00]]) <https://tools.ietf.org/html/rfc1521#section-5.2>
- [280] [CITE@en[rfc2065]], [TIME[2021-06-09T03:35:31.000Z]] <https://datatracker.ietf.org/doc/html/rfc2065#page-40>
- [43] [CITE@en[RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies]] ([TIME[2015-03-22 13:13:15 +09:00]] 版) <https://tools.ietf.org/html/rfc2045#section-6.8>
- [826] [CITE@en[RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0]] ([TIME[2012-02-18 23:25:56 +09:00]] 版) <https://tools.ietf.org/html/rfc1945#section-11.1>
- [183] [CITE@en[RFC 2068 - Hypertext Transfer Protocol -- HTTP/1.1]] ([TIME[2018-01-28 09:40:08 +09:00]]) <https://tools.ietf.org/html/rfc2068#section-11.1>
- [828] [CITE@en[RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication]] ([TIME[2012-01-09 21:04:30 +09:00]] 版) <https://tools.ietf.org/html/rfc2617#section-2>

[FIG(quote)[
[FIGCAPTION[
[73] [CITE@en[draft-ietf-usefor-cancel-lock-01 - Cancel-Locks in Usenet articles.]]
([TIME[2016-10-31 14:51:38 +09:00]])
<https://tools.ietf.org/html/draft-ietf-usefor-cancel-lock-01>
]FIGCAPTION]

> The encoding of the binary key or lock is performed in accordance with
the Base64 Transfer Encoding defined in '''['''RFC-2045''']'''.

]FIG]

]REFS]

[282] [CITE@en[rfc2060]], [TIME[2021-06-09T03:43:30.000Z]] <https://datatracker.ietf.org/doc/html/rfc2060#page-66>

[[ABNF]] 構文定義のみ

-*-*-

[74] [[PGPメッセージ交換形式]]もまた、独自に [[Base64]] を規定しており、
[DFN[Radix-64]] と呼んでいます [SRC[>>159, >>160, >>161]]。 

[162] [[RFC 1991]] の規定は曖昧なものでした。

[163] [[RFC 2440]] や [[RFC 4880]] は、 [[MIME]] の [[RFC 2045]]
と同内容の [[Base64]] を規定しています。歴史的経緯によるものか、
[[MIME]] の [[Base64]] への言及は一切ありません。
しかし明らかに同じテキストを流用しています。
ですが全く同じではなく、解釈次第ではこちらの定義の方が厳密ともいえます。

[FIG(list middle)[ [46] [[Radix-64]] の[[応用]]
- [[ASCII Armor]]
]FIG]

[REFS[
- [159] [CITE@en[RFC 1991 - PGP Message Exchange Formats]] ([TIME[2018-01-28 20:52:48 +09:00]]) <https://tools.ietf.org/html/rfc1991#section-2.4>
- [160] [CITE@en[RFC 2440 - OpenPGP Message Format]] ([TIME[2018-01-21 17:16:48 +09:00]]) <https://tools.ietf.org/html/rfc2440#section-6.3>
- [161] [CITE@en[RFC 4880 - OpenPGP Message Format]] ([TIME[2018-01-21 18:54:46 +09:00]]) <https://tools.ietf.org/html/rfc4880#section-6.3>
]REFS]



[274] [CITE@en[RFC 2801 - Internet Open Trading Protocol - IOTP Version 1.0]], [TIME[2021-04-11T11:36:33.000Z]], [TIME[2021-04-12T11:21:08.173Z]] <https://tools.ietf.org/html/rfc2801#page-52>


[276] [CITE@en[RFC 3252 - Binary Lexical Octet Ad-hoc Transport]], [TIME[2019-03-03T20:11:48.000Z]], [TIME[2021-04-21T08:51:06.486Z]] <https://tools.ietf.org/html/rfc3252#section-2.1>

>This RFC
REQUIRES the contents of the payload to be encoded in the base-64
encoding of RFC 2045 [RFC2045], but removes the requirement that the
encoded output MUST be wrapped on 76-character lines.


[283] [CITE@en[rfc3885]], [TIME[2021-06-09T04:44:51.000Z]] <https://datatracker.ietf.org/doc/html/rfc3885#section-1>

字母の [[ABNF]] 定義のみ。

** IETF の Base64

[15] [[IETF]] はその後 [[Base64]] (と [[Base32]] と [[Base16]]) のみを定める
[[RFC]] を発行しました [SRC[>>6, >>24]]。

[30] [[MIME]] 式の [[base64]] と、 [[base64url]] (>>833) との2種類が定義されています。
両者は[[字母]]のみが異なっています。

[164] [[MIME]] 式のものは、 [[MIME]] や [[OpenPGP]] に由来するものですが、
いくつか異なる点もあります。

[165] [[詰め]]は、原則として[MUST[必須]]ですが、[[応用]]は省略可能と定めることができます。
しかし[[詰め]]が省略された場合にどう処理しなければならないかは規定されていません。

[167] [[RFC 3548]] にはありませんでしたが、 [[RFC 4648]] は、
[[詰め]]の前の[[字母]]の選択時に余った[[ビット]]は [N[0]]
としなければ[MUST[ならない]]としています。
そうでない場合、[[復号]]時に拒絶しても構わないとされています。

[168] [[復号]]時に[[字母]]以外が含まれる場合、
原則として拒絶しなければ[MUST[ならず]]、
[[応用]]はそれ以外の処理方法を定めても良い、とされています。
[[電子メール]]のように行長制限が必要な場合には[[改行]]を挿入することを選べますが、
基本的には[[改行]]は含めないことになっているのが [[MIME]] との最大の違いです。
同様に[[復号]]時に不正な[[詰め]]も無視すると定めても良いことになっています。

[169] これらの [[RFC]] でも、完全な[[復号]]の方法は定められていません。

[FIG(list middle)[ [33] [[RFC 3548]] [[MIME]] 式 [[Base64]] の[[応用]]
- [[XMPP]] ([[RFC 3920]])
-- [284] [CITE@en[rfc3920]], [TIME[2021-06-22T06:16:57.000Z]] <https://datatracker.ietf.org/doc/html/rfc3920#section-6.1>
-- [285] [CITE@en[rfc3920]], [TIME[2021-06-22T06:20:48.000Z]] <https://datatracker.ietf.org/doc/html/rfc3920#section-14.9>
--- [286] エラー処理の規定あり
- [[Atom 1.0]] [CODE[atom:content]] (>>36)
]FIG]

[FIG(list middle)[ [67] [[RFC 4648]] [[MIME]] 式 [[Base64]] の[[応用]]
- [185] [[基本認証]] [[credentials]] [SRC[>>184]]
- [[YANG]] [SRC[>>72]]
- [[RFC 7804]] [SRC[>>61]]
- [[RFC 7730]] ([CODE[CRLF]] / [CODE[CR]] 挿入可) [SRC[>>60]]
- [[RFC 7468]] [CODE[.pem]] (>>197)
- [[Base64符号化SPKI Fingerprint]]
- [[[CODE[x5c]]のJSON配列]]
- [290] [CITE@en[Specification]], [TIME[2021-09-20T16:55:41.000Z]], [TIME[2021-09-21T06:46:43.833Z]] <https://amzn.github.io/ion-docs/docs/spec.html#blob>


[HISTORY[
- [CODE(HTTP)@en[Sec-WebSocket-Key:]] [SRC[旧 RFC、旧 [CITE[Fetch Standard]]]]
]HISTORY]
]FIG]

[36]
[[RFC 4287]] の [[Atom 1.0]] における [CODE[atom:content]] では、
[[RFC 3548]] の [[MIME]] 式 [[Base64]] が使われています [SRC[>>177]]。
ただし、前後に[[空白]]があっても良いこと、
[[改行]]は [CODE[U+000A]] とすることが定められています [SRC[>>177]]。
この[[改行]]の定めが何を意味するかは不明瞭です。
[[RFC 3548]] によれば[[応用]]が明確に認めない限り[[改行]]の挿入は認められませんが、
[[RFC 4287]] が明確に認めているとは言えず、
しかしそうだとすると [[RFC 4287]] の記述は理解不能となります。

[197] [[RFC 7468]] は、 [CODE[.pem]] ファイルの [[Base64]]
を [[RFC 4648]] の [[MIME]] 式 [[Base64]] としています。
ただし、生成時には最終行以外を64文字丁度とすることと定めています
(これは [[PEM]] に由来する制約です)。
解釈時には[[空白]]を含む[[字母]]以外を無視することを認めています。
[[ABNF]] 構文上は[[詰め]]の省略が認められているようですが、
本文には明確な規定がなく、意図は不明です。
([[ABNF]] 構文は通常、緩め、厳密の3種類が用意されています。)

[REFS[
- [6] [CITE@en[RFC 3548 - The Base16, Base32, and Base64 Data Encodings]] ([TIME[2018-01-21 17:19:42 +09:00]]) <https://tools.ietf.org/html/rfc3548>
- [24] [CITE@en[RFC 4648 - The Base16, Base32, and Base64 Data Encodings]] ([TIME[2018-01-28 17:12:45 +09:00]]) <https://tools.ietf.org/html/rfc4648>
- [177] [CITE@en[RFC 4287 - The Atom Syndication Format]] ([TIME[2018-01-28 12:33:10 +09:00]]) <https://tools.ietf.org/html/rfc4287#section-4.1.3.3>
- [184] [CITE@en[RFC 7617 - The 'Basic' HTTP Authentication Scheme]] ([TIME[2018-02-02 23:41:22 +09:00]]) <https://tools.ietf.org/html/rfc7617#section-2>

[FIG(quote)[
[FIGCAPTION[
[60] [CITE@en[RFC 7730 - Resource Public Key Infrastructure (RPKI) Trust Anchor Locator]]
([TIME[2016-03-02 07:04:14 +09:00]] 版)
<https://tools.ietf.org/html/rfc7730>
]FIGCAPTION]

>       3)  a subjectPublicKeyInfo '''['''RFC5280''']''' in DER format '''['''X.509''']''',
encoded in Base64 (see Section 4 of '''['''RFC4648''']''').  To avoid long
lines, <CRLF> or <LF> line breaks MAY be inserted into the
Base64-encoded string.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[61] [CITE@en[RFC 7804 - Salted Challenge Response HTTP Authentication Mechanism]]
([TIME[2016-04-01 08:53:49 +09:00]] 版)
<https://tools.ietf.org/html/rfc7804#section-5.1>
]FIGCAPTION]

> Base64: An encoding mechanism defined in Section 4 of '''['''RFC4648''']'''
that converts an octet string input to a textual output string
that can be easily displayed to a human.  The use of base64 in
SCRAM is restricted to the canonical form with no whitespace.

]FIG]

- [72] [CITE@en[RFC 7950 - The YANG 1.1 Data Modeling Language]]
([TIME[2016-09-15 03:32:37 +09:00]])
<https://tools.ietf.org/html/rfc7950#section-9.8>

]REFS]


[287] [CITE@en[rfc3977]], [TIME[2021-06-22T06:47:28.000Z]] <https://datatracker.ietf.org/doc/html/rfc3977#section-3.2.1>

[288] [CITE@en[rfc3977]], [TIME[2021-06-22T06:48:17.000Z]] <https://datatracker.ietf.org/doc/html/rfc3977#page-98>

** [CODE[xs:base64Binary]]

[63] [[XML Schemaデータ型]] [DFN[[CODE[xs:base64Binary]]]]
は、 [[MIME]] の [[RFC 2045]] の定義を参照しつつ、
独自の構文を規定しています [SRC[>>172]]。

[173] [[US-ASCII]] ベースの [[RFC 2045]] と違って、 [[XML Schema]]
は [[Unicode]] ベースとなっています。 ([[文字]]レベルで見れば実質的な違いはありません。)

[174] 本来の[[字母]]の他に [[XMLの空白]]が任意の位置に認められることになっています。
ただし [[XML Schema]] の[[正規化]]を経た[[字句形]]の構文上は途中に [CODE[U+0020]]
各1つのみの挿入が認められることになっています。
[[MIME]] とは違って行長制限はありません。

[176] [[正準字句形]]では[[空白]]は認められないことになっています。

[175] [[詰め]]は必須であり、[[詰め]]の前の[[字母]]の選択時に足りない[[ビット]]は [N[0]]
で埋めなければならないことになっています。

[REFS[
- [172] [CITE@EN[XML Schema Part 2: Datatypes Second Edition]] ([TIME[2017-10-02 19:29:02 +09:00]]) <https://www.w3.org/TR/xmlschema-2/#base64Binary>
]REFS]

** Web Base64

[87] [[Web]] では、 [[エラー処理]]を含め正確な[[アルゴリズム]]として[[符号化]]
(>>89) と[[復号]] (>>91) を定義した
[DFN[forgiving base64]] [SRC[>>86]] を用いています。

[88] 正常な入力のみに限ったとき、 [[RFC 4648]] 第4章の [[Base64]] と等価です。

[112] [[詰め]]は、必ず生成されますが、省略されても[[復号]]には成功します。
[[詰め]]の直前の[[字母]]の余分な[[ビット]]は、無視されます。

[113] [[空白][HTMLの空白]]は生成されませんが、無視されます。
[[字母]]と[[空白][HTMLの空白]]以外が含まれる場合や、
不正な[[詰め]]が含まれる場合は、[[復号]]に[[失敗]]します。

[114] [CITE[Infra Standard]] の [[forgiving base64]] が [[Base64]]
の歴史上最も厳密な定義となっており、特に事情がない場合、これを採用するのが望ましいと思われます。

** UTF-7 修正 Base64

[2] [[UTF-7]] は、[DFN[[RUBYB[修正Base64]@en[Modified Base64]]]]と称する[[変種]]を定義していました
[SRC[>>44, >>47]]。

[178] [[MIME]] の [[RFC 1521]] や [[RFC 2045]] を参照しつつ、
[[詰め]]の [CODE[=]] は使わないこととしていました。
[[復号]]時には、16ビット単位の列として解釈した時に余った[[ビット]]は捨てることとされていました。
余った[[ビット]]が [N[0]] でないものは [[ill-formed]] であるとされていましたが、
それをどう処理するべきかは明記されていませんでした。

[179] [[UTF-7]] では[[字母]]でない[[文字]]を[[修正Base64]]部分の終わりとみなすことになっていました。
従って[[改行]]の挿入は認められていませんでしたし、[[字母]]以外の混入時の[[復号]]の処理も明確でした。
ただし[[改行]]を挿入しないため行長制限を超えてしまうデータが認められると明記はしていませんでした。

[REFS[
- [44] [CITE@en[RFC 1642 - UTF-7 - A Mail-Safe Transformation Format of Unicode]] ([TIME[2018-01-21 18:01:49 +09:00]]) <https://tools.ietf.org/html/rfc1642#page-5>
- [47] [CITE@en[RFC 2152 - UTF-7 A Mail-Safe Transformation Format of Unicode]] ([TIME[2018-01-28 16:55:03 +09:00]]) <https://tools.ietf.org/html/rfc2152#page-5>
]REFS]

-*-*-

[7] [[IMAP]] の[[修正UTF-7]] は、 [[UTF-7]] の[[修正Base64]]を更に改変し、
[[字母]] [CODE(char)[/]] の代わりに [CODE(char)[,]] を使うとしています
[SRC[>>182, >>181]]。

[REFS[
- [182] [CITE@en[RFC 2060 - Internet Message Access Protocol - Version 4rev1]] ([TIME[2018-01-28 19:02:32 +09:00]]) <https://tools.ietf.org/html/rfc2060#section-5.1.3>
- [181] [CITE@en[RFC 3501 - INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1]] ([TIME[2018-02-01 03:51:41 +09:00]]) <https://tools.ietf.org/html/rfc3501#section-5.1.3>
- [180] [CITE[RFC Errata Report » RFC Editor]] ([TIME[2018-02-04 00:33:46 +09:00]]) <https://www.rfc-editor.org/errata_search.php?rfc=3501>
-- 旧 [CITE[RFC ERRATA]] 
<http://www.rfc-editor.org/cgi-bin/errata.pl#rfc3501>
]REFS]

** URL 安全 Base64

[833] [DFN[[[modified Base64 for URL]]]] [SRC[>>829]] あるいは [DFN[[[base64url]]]] と呼ばれる変種は、
[[URL]] で利用しやすくした [[Base64]] の一種です。 [[Web]]
関係の分野でよく用いられるようになってきました。

[277] 
[[Base64]] のバリエーションの中では、
[[MIME]]
式に次いで2番目に普及していると思われます。

[834] [[MIME]] 式の [[Base64]] と [[base64url]] との違いは、
次の通りです。

- [835] [[字母]]の [CODE(char)[[[+]]]] と [CODE(char)[[[/]]]] のかわりに [CODE(char)[[[-]]]]
と [CODE(char)[[[_]]]] を使う
- [836] [[詰め]]の [CODE(char)[[[=]]]] は省略する
- [837] 行長制限を設けず、[[改行]]を挿入しない

-*-*-

[838] 出典としてはしばしば [[Wikipedia]] [SRC[>>829]] が参照されます。
そんなあやふやなものを参照して技術基盤として大丈夫なんだろうか、
と不安になりますが、案外よく参照されています。

[839] 公的な文書としては [[RFC]] (>>30) があり、ファイル名や [[URL]]
で安全なものとして紹介されています。ただし [[RFC]] は原則として[[詰め]] [CODE(char)[[[=]]]]
は省略できないとしており、一般的な実装とは異なっています。

;; [17] [CODE[=]] は [[URL]] では [[query][URL query]] などで特別な意味を持つことがあるので、
あまり安全ではありません。 [[RFC]] は原則を貫こうとするあまり、
一般的な実装が意図的に加えた改変を無視しているのです。

;; [22] 実際には [CODE[-]] が[[ファイル名]]の先頭に来るのは必ずしも安全とはいえません。
[[URL]] で安全と言うのに留めておけばいいのに、[[RFC]] は余計な説明を加えています。

[840] [[RFC]] は既存の利用例として[[メーリング・リスト]]の記事を参照していますが、
[[URL]] が変わってしまったのか、関係ない記事になっています。本来指すべきだったと思われる
>>831、>>832 によると、元々は [[Freenet]] で使われていたのを採用したようです。

[293] 
[[Google Apps Script]]
の[[標準ライブラリー]]の
[CODE[base64EncodeWebSafe]],
[CODE[base64DecodeWebSafe]]
は
[DFN[base-64 web-safe encoded string]]
なるものに対応しています。
[SRC[>>292]]
これは[[詰め]] [CODE[=]] ありの [[base64url]] のようです。

;; [294] しばしば [[JWT]] など[[詰め]]ないところで使われてトラブルを起こしているようです。
[[HTTP]] [[基本認証]] (本来は元々の [[Base64]] の系統) に使われている事例まであるようです。

-*-*-

[229] [[I-JSON]] は、 [[RFC 4648]] [[base64url]] を使う[SHOULD[べき]]としています。
([[JSON]] で通常の [[Base64]] では不都合な理由はなく、敢えて [[base64url]]
を選択した理由は不明です。)

[221] 
[[JSON-Base64]] は、 [[RFC 4648]] の [[URL安全Base64]] を参照しつつも、
独自に定義しています。 [[Base64]] の[[字母]]を置き換え、
[CODE[=]] を削除したものとなっています [SRC[>>220]]。
[[RFC]] を参照しているものの、 [[RFC]] が改変する前の本来の
[[URL安全Base64]] ということになります。

[234] [[RFC 7515]], [[RFC 7522]], [[RFC 7636]] [DFN[Base64url Encoding]] [SRC[>>233, >>54, >>56]] は、
[[RFC 4648]] [[base64url]] の[[詰め]]を禁止し、
[[空白]]その他の挿入も明示的に禁止しています。
また [[RFC 7515]] は[[符号化]]と[[復号]]の、
[[RFC 7636]] は[[符号化]]の実装例も掲載しています。
(>>242 も参照)

[236]
結局 [[IETF]] の[[プロトコル]]でも[[詰め]]のない [[base64url]] が主流にみえます。
敢えて世間一般と違うものを定義した [[RFC]] 
の意義は何だったのでしょうか。そして利用実態に反したまま改訂せずに放置している
[[IETF]] の意図は何なのでしょうか。


[REFS[
- [831] [CITE[please prefer base 64 over base 32 (was: Re: '''['''p2p-hackers''']''' Bitzi (was Various identifier choices))]] ([TIME[2006-12-10 07:13:19 +09:00]] 版) <http://zgp.org/pipermail/p2p-hackers/2001-September/000317.html>
- [832] [CITE[please prefer base 64 over base 32 (was: Re: '''['''p2p-hackers''']''' Bitzi (was Various identifier choices))]] ([TIME[2006-12-10 07:13:19 +09:00]] 版) <http://zgp.org/pipermail/p2p-hackers/2001-September/000316.html>
- [829] [CITE@en[Base64 - Wikipedia, the free encyclopedia]] ([TIME[2012-05-01 23:31:28 +09:00]] 版) <http://en.wikipedia.org/wiki/Base64#URL_applications>
- [220] [CITE[JSON-Base64 (JB64) File Format Specification]] ([TIME[2017-05-31 14:00:28 +09:00]]) <https://jb64.org/specification/>
-
[292] 
[CITE@ja-x-mtfrom-en[Class Utilities | Apps Script | [[Google]] Developers]], [TIME[2022-08-17T17:43:16.000Z]], [TIME[2022-09-11T04:58:17.971Z]] <https://developers.google.com/apps-script/reference/utilities/utilities>



]REFS]

-*-*-

[241] 
[[復号]]の方法は厳密には規定されていません。

[242] [DFN[RFC 7515][RFC 7515 base64url復号]] は
「Base64url-decode the encoded representation of [VAR[(入力データ)]],
following the restriction that no line breaks, whitespace, or
other additional characters have been used.」
という表現を用いています [SRC[>>240]]。
これが満たされないとき[[検証]]は[[失敗]]することとなり、
緩い[[復号]]を用いないことを求めています。
ただし[[詰め]]の扱いは明言していません。

[243] [[RFC 7515]] の[[復号]]のサンプルコード [SRC[>>233]] 
は、次のような挙動を示します。
ただ、あくまで実装例に過ぎず、[[復号]]方法の規定とは到底言えません。

- [244] [CODE[+]] や [CODE[/]] は [CODE[-]] や [CODE[_]] とそれぞれ同義とみなされる
- [245] 末尾の [CODE[=]] はあってもなくても同義とみなされる
- [246] 文字数を [N[4]] で割って [N[1]] となるなら、[[復号]]は失敗とする
- [247] その他は通常の [[Base64]] の方法による

;; [270] >>244 は >>242 の規定と矛盾します。

[278] 
仕様書がこんな状態なので、実装は混乱していることが予想されます。
[[base64url]] データの送信者は、壊れたデータを送信しないよう、
慎重に実装することが望まれます。
[[base64url]] データを受信する実装を作る開発者は、
既成の[[ライブラリー]]を流用するなら、
その[[ライブラリー]]の挙動を慎重に調査し、
不正な入力が与えられても適切に動作するよう、
注意が必要です。

-*-*-

[75] 他の [[Base64]] の変種同様、[[字母]]を置き換えるだけなので簡単に実装できます。
両対応の[[ライブラリー]]も珍しくありません。

[842] [[Perl]] の[[標準モジュール]]である [CODE(perl)@en[[[MIME::Base64]]]] [SRC[>>841]]
に実装されています。 [[Perl]] では今後はこちらが標準的な実装となっていくと思われます。
[[Wikipedia]] [SRC[>>829]] が出典とされています。
[TIME[2012-05-23T10:20:19.800Z]]

[844] >>843 は >>841 が実装される前によく用いられていました。 [[Python]]
の実装に倣った [SRC[>>843, >>845]] としつつ、 [[Wikipedia]] [SRC[>>829]] も引用しています。

[849] [[Python]] の実装というのは >>848 でしょうが、こちらは >>841、>>843
とは違って [CODE(char)[[[=]]]] を省略しません。 >>839 に従っている実装です。

;; [850] 最初からそうだったのか、それとも [[Perl]] の実装が派生した後に動作が変わったのかは不明です。

;; [851] なお、 [[Python]] の実装は >>835 の2文字を任意の文字に変更できるようですw

[279] 
[[MIME]] 式と一部の[[字母]]が違うだけなので、
[[字母]]を置き換えてから [[MIME]] 式で[[復号]]するような実装が蔓延っています。
簡単に実装できるのは結構ですが、
この方式だと
[[MIME]] 式 [[Base64]] の入力や、
[[MIME]] 式 [[Base64]] と [[base64url]] の両方の[[字母]]が混在している入力まで[[復号]]できてしまいます。
そんな実装が混在している (かもしれない) という現状は、
[[相互運用性]]や[[セキュリティー]]の問題の温床です。



[REFS[
- [841] [CITE[MIME::Base64 - search.cpan.org]] ([TIME[2012-05-23 19:19:16 +09:00]] 版) <http://search.cpan.org/dist/MIME-Base64/Base64.pm#encode_base64url(_$bytes_)>
- [843] [CITE[MIME::Base64::URLSafe - search.cpan.org]] ([TIME[2012-05-23 19:21:18 +09:00]] 版) <http://search.cpan.org/dist/MIME-Base64-URLSafe/lib/MIME/Base64/URLSafe.pm>
- [845] [CITE[Kazuho@Cybozu Labs: URL と Base64]] ([TIME[2012-05-23 19:26:17 +09:00]] 版) <http://labs.cybozu.co.jp/blog/kazuho/archives/2006/01/url_base64.php>
-[848] [CITE[18.12. base64 — RFC 3548: Base16, Base32, Base64 Data Encodings — Python v2.7.3 documentation]] ([TIME[2012-05-23 16:26:05 +09:00]] 版) <http://docs.python.org/library/base64.html>
]REFS]

-*-*-

[FIG(middle list)[ [66] [[RFC 4648]] [[base64url]] の[[応用]]
- [CODE(HTTP)@en[HTTP2-Settings:]] ([[詰め]]禁止)
- [CODE[keys][PushSubscriptionJSON]] ([[詰め]]なし)
- [[RFC 6920]] [CODE[ni:]] ([[詰め]]なし)
]FIG]

[FIG(middle list)[ [237] [[RFC 7515]], [[RFC 7522]], [[RFC 7636]] [[base64url]] の[[応用]]
- [[RFC 7515]]
-- [[JWS]]
--- [CODE[x5t]]
--- [CODE[x5t#S256]]
--- [[VAPID]]
- [[RFC 7516]] [SRC[>>296]]
-- [[JWE]]
- [[RFC 7517]] [SRC[>>297]]
-- [[JWK]]
- [[RFC 7522]]
- [[RFC 7636]]
- [CODE[vapid k][vapid]]
- [[[CODE[application/webpush-options+json]] [CODE[vapid]]][application/webpush-options+json]]
- [CODE[applicationServerKey]] 
]FIG]

[263] [DFN[[CODE[BASE64URL([VAR[OCTETS]])]]]]
のような[[仕様書]]上の表記法が使われています [SRC[>>262, >>296, >>297]]。

[235] いくつかの [[RFC]] は、[[バイナリーデータ]]を [[RFC]]
として記述するための便宜上の方法として [[base64url]] を使っています。
[[RFC 4648]] を引用しつつ、 [[RFC]] の制約上空白を挿入することとしています。
明記はされていませんが、[[詰め]]も省略されています。

[FIG(list)[ [238] 表示用の [[base64url]] の事例
- [CITE@en[RFC 8188 - Encrypted Content-Encoding for HTTP]] ([TIME[2018-12-30 20:20:21 +09:00]]) <https://tools.ietf.org/html/rfc8188#section-3>
- [CITE@en[RFC 8291 - Message Encryption for Web Push]] ([TIME[2018-12-30 17:45:08 +09:00]]) <https://tools.ietf.org/html/rfc8291#section-5>
]FIG]

[266] 
[DFN[Base64urlUInt]]
は、
[[正整数]]または [N[0]] の値について、
[[符号無し]][[大エンディアン]]表現を[[オクテット列]]としたとき、
これを
[[base64url]]
[[符号化]]したものです。 
このとき[[オクテット列]]は、
当該[[整数値]]を表現するために必要な最低数の[[オクテット]]のみ用いなければ[MUST[なりません]]。
[SRC[>>265]]

[EG[
[267] 
[N[0]]
は 
[CODE[AA]]
となります。
[SRC[>>265]]
]EG]



[REFS[
- [239] [[RFC 7515]]
-- [233] [CITE@en[[[RFC 7515]] - JSON Web Signature ([[JWS]])]] ([TIME[2018-12-30 17:16:56 +09:00]]) <https://tools.ietf.org/html/rfc7515#page-6>
-- [240] [CITE@en[[[RFC 7515]] - JSON Web Signature ([[JWS]])]] ([TIME[2018-12-30 17:16:56 +09:00]]) <https://tools.ietf.org/html/rfc7515#page-17>
- [295] [[RFC 7516]]
-- [296] [CITE@en[[[RFC 7516]] - JSON Web Encryption (JWE)]], [TIME[2022-11-23T02:43:36.000Z]] <https://datatracker.ietf.org/doc/html/rfc7516#section-1.1>
- [264] [[RFC 7518]]
-- [262] [CITE@en[[[RFC 7518]] - JSON Web Algorithms ([[JWA]])]], [TIME[2019-11-27 04:11:14 +09:00]] <https://tools.ietf.org/html/rfc7518#section-1.1>
-- [265] [CITE@en[[[RFC 7518]] - JSON Web Algorithms (JWA)]], [TIME[2019-11-27 04:11:14 +09:00]] <https://tools.ietf.org/html/rfc7518#section-2>
- [297] 
[CITE@en[[[RFC 7517]]: JSON Web Key (JWK)]], [TIME[2022-11-25T08:30:17.000Z]] <https://www.rfc-editor.org/rfc/rfc7517.html#section-1.1>


[FIG(quote)[
[FIGCAPTION[
[54] [CITE@en[RFC 7522 - Security Assertion Markup Language (SAML) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants]]
([TIME[2015-05-28 13:43:45 +09:00]] 版)
<https://tools.ietf.org/html/rfc7522>
]FIGCAPTION]

>  The SAML Assertion XML data MUST be encoded using base64url, where
the encoding adheres to the definition in Section 5 of RFC 4648
'''['''RFC4648''']''' and where the padding bits are set to zero.  To avoid the
need for subsequent encoding steps (by "application/x-www-form-
urlencoded" '''['''W3C.REC-html401-19991224''']''', for example), the base64url-
encoded data MUST NOT be line wrapped and pad characters ("=") MUST
NOT be included.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[56] [CITE@en[RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients]]
([TIME[2015-09-17 06:51:32 +09:00]] 版)
<https://tools.ietf.org/html/rfc7636>
]FIGCAPTION]

> Base64 encoding using the URL- and filename-safe character set
defined in Section 5 of '''['''RFC4648''']''', with all trailing '='
characters omitted (as permitted by Section 3.2 of '''['''RFC4648''']''') and
without the inclusion of any line breaks, whitespace, or other
additional characters.  (See Appendix A for notes on implementing
base64url encoding without padding.)

]FIG]

]REFS]


*** 処理

[248] [[符号化]]は、[[バイト列]][VAR[入力]]を、次のようにするべきです。

[FIG(steps)[
= [249] [VAR[結果]]を、[VAR[入力]]を [[forgiving-base64 encode]] 
した結果に設定します。
= [250] [VAR[結果]]中の [CODE[+]] を、すべて [CODE[-]]
に置き換えます。
= [251] [VAR[結果]]中の [CODE[/]] を、すべて [CODE[_]]
に置き換えます。
= [252] [VAR[結果]]中の [CODE[=]] を、すべて削除します。
= [253] [VAR[結果]]を返します。
]FIG]

[254] [[復号]]は、[[文字列]][VAR[入力]]を、次のようにするべきです。

[FIG(steps)[
= [255] [VAR[入力]]中の [CODE[-]] を、すべて [CODE[+]]
に置き換えます。
= [256] [VAR[入力]]中の [CODE[_]] を、すべて [CODE[/]]
に置き換えます。
= [257] [VAR[入力]]中に
[CODE[+]], [CODE[/]], [CODE[=]],
[[ASCII英数字]]のいずれでも''ない''[[符号位置]]が含まれる場合、
== [258] [[失敗]]を返し、ここで停止します。
= [259] [VAR[入力]]を [[forgiving-base64 decode]] した結果を返します。
]FIG]

** HTTP Certificate Store Interface の Base64

[300] 
[[HTTP Certificate Store Interface]]
は
[[Base64]] 
の一種を使っています。
[SRC[>>299]]

[301] 
仕様書では
「Base64」,
「Base64 encoding」,
「base64 encoding」,
「base64-encoded」
といった表現が使われています。
[SRC[>>299]]

[302] 
末尾の [CODE[=]] は省略しなければならないとされています。
[SRC[>>299]]

[303] 
実装は [[ASCII英数字]]、 [CODE[+]]、 [CODE[/]] 以外が含まれるとき、
拒絶しなければ[MUST[ならない]]とされています。
[SRC[>>299]]

[304] 
このように [[IETF]] にしてはしっかり[[エラー処理]]が規定されているにも関わらず、
なぜか
「Base64」
とは何かという最も重要な部分が規定されていません。

[305] 
>>303 から、 [[MIME]] や [[PEM]] の [[Base64]] から[[空白]]や
[CODE[=]]
を禁止したものだと'''推測'''はできますが...

[REFS[

- [299] [CITE@en[[[RFC 4387]]: Internet X.509 Public Key Infrastructure Operational Protocols: Certificate Store Access via HTTP]], [TIME[2023-07-03T08:16:29.000Z]], [TIME[2023-07-03T08:41:12.945Z]] <https://www.rfc-editor.org/rfc/rfc4387.html#section-2.1>

]REFS]

** その他のバリエーション

[306] 
[[BUCS]] と共に使う[[外字]]の[[グリフ]]記述用の [[Base64]] 案は
[[ASCII英数字]]と [CODE[.][FULL STOP]] と [CODE[/]]
を使っていました。
[SEE[ [[BUCS]] ]]

[9] [CODE(URI)[[[urn:urn-5]]]] [[URN]] [[名前空間]]で使っている Base64
変種は、 [CODE(char)[/]] の代わりに [CODE(char)[-]]
を使います。 (URN では [CODE(URI)[/]] が使えないため。)
また、詰め文字は使いません。
(''Namespace ID: urn-5'' <http://www.iana.org/assignments/urn-informal/urn-5>)

[16] [[RFC 3548]] 曰く、 MIME Base64 ではファイル名や [[URI]] 
で安全ではないので、 [CODE(char)[/]] の代わりに [CODE(char)[~]] 
を使う提案があったそうです。しかし [CODE(char)[~]] もやはりファイル・システムや 
URI で安全とは言えません。

[18] [[M$XML]] は [CODE(char)[/]] の代わりに [CODE(char)[*]] 
を使っていたそうです。最近の版では両方認識するそうです。

[20] [[OpenToken]] [SRC[>>19]] は[[クッキー]]で使うためとして、 [[RFC 4648]]
の [[Base64]] の[[詰め文字]]を [CODE[[[=]]]] ではなく [CODE[[[*]]]]
に変えたものを採用しています [SRC[>>19]]。

[847] [SRC[>>846]]
>
,*採用アプリ	,*変換方式
,Hibernate	,"+/ → *-"
,IMAP4	,"+/ → +,"
,IRCu	,"+/ → []"
,Python	,"+/ → -_"
,正規表現フリー注2	,"+/ → !-"


[REFS[
- [19] [CITE@en[draft-smith-opentoken-02 - OpenToken]] ([TIME[2014-10-16 18:11:31 +09:00]] 版) <https://tools.ietf.org/html/draft-smith-opentoken-02#section-3.1>
- [846] [CITE[Kazuho@Cybozu Labs: URL と Base64]] ([TIME[2012-05-23 19:26:17 +09:00]] 版) <http://labs.cybozu.co.jp/blog/kazuho/archives/2006/01/url_base64.php>
]REFS]

-*-*-

[29]
[[Norton AntiSpam]] は [CODE(ABNF)[[[encoded-word]]]] の最後の
[CODE(MIME)[=]] を省くそうです。 [SRC[mew-dist 25264]]
もちろんこの実装は MIME 違反です。

[39]
機械的に電子メイルを生成する類のプログラムで、
末尾に4つも [CODE(MIME)@en[=]] を付けるとんでもない符号化するものがあるそうです。
[WEAK[(しかも改善するように要求したら使っている [[MUA]] が悪いのだろうと言われたとか。。。)]]

([[名無しさん]] [sage] [WEAK[2005-12-10 07:32:30 +00:00]])

[45]
[[RFC 4387]] では固定長の[[オクテット列]]を符号化するため、常に最後が [CODE[=]] になってしまうので、
[CODE[=]] は省略することになっています [SRC[>>884]]。

[55]
[[Perl]] の [CODE(perl)@en[[[Digest::MD5]]]] や
[CODE(perl)@en[[[Digest::SHA1]]]] が出力する [[Base64]]
化[[文字列]]は、[[詰め]]が省略されています [SRC[>>853]] 。

[REFS[
- [884] [CITE@en[RFC 4387 - Internet X.509 Public Key Infrastructure Operational Protocols: Certificate Store Access via HTTP]] ([TIME[2014-06-08 08:24:17 +09:00]] 版) <http://tools.ietf.org/html/rfc4387#section-2.1>
- [853] [CITE[Digest::SHA - search.cpan.org]] ([TIME[2013-09-21 12:18:41 +09:00]] 版) <http://search.cpan.org/dist/Digest-SHA/lib/Digest/SHA.pm#PADDING_OF_BASE64_DIGESTS>
]REFS]

-*-*-

[189] [[IMAP4]] の [CODE[AUTHENTICATE]] [[命令]]は、 [[base64]]
で[[符号化]]するとされていますが、その定義は示されていません
[SRC[>>186, >>187, >>188]]。

[190] [[インターネットメール]]の[[プロトコル]]であるから [[MIME]]
の [[Base64]] ではないかと推測したいところですが、
[[ABNF]] 構文が示されており、そこでは[[改行]]が認められていません。
本文中も単数の a line となっており、複数行は認められないようです。
しかし符号化されるデータが [[MIME]] 式 [[Base64]] で1行に収まる保証はありません。

[191] 構文は、 [[MIME]] 式の[[字母]]と[[詰め]]を認めており、
それ以外の[[文字]]は一切認めていません。[[詰め]]が含まれる数は、正しくなければなりません。
[[詰め]]の前の[[字母]]の制約は構文上は現れていません。

[REFS[
- [186] [CITE@en[RFC 1730 - Internet Message Access Protocol - Version 4]] ([TIME[2018-01-21 18:00:58 +09:00]]) <https://tools.ietf.org/html/rfc1730#section-6.2.1>
- [187] [CITE@en[RFC 2060 - Internet Message Access Protocol - Version 4rev1]] ([TIME[2018-01-28 19:02:32 +09:00]]) <https://tools.ietf.org/html/rfc2060#section-6.2.1>
- [188] [CITE@en[RFC 3501 - INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1]] ([TIME[2018-02-01 03:51:41 +09:00]]) <https://tools.ietf.org/html/rfc3501#section-6.2.2>
]REFS]

** 不透明な Base64 字母列

[273] 
普通 [[Base64]] は他の誰かが[[復号]]することを期待して用いられるものですが、
それを期待しない、あるいは自分自身しか[[復号]]しないので[[相互運用性]]が不要なところでも用いられる場合があります。
それなら任意のデータで構わないのですが、
[[プロトコル]]の文脈的な制約からまったく任意の[[バイト列]]を認めるわけにもいかず、
一定の制約は設けておきたい、
というようなノリで、
[[Base64]] のようだけどそうとも言い切らない構文が使われることがあります。


[269] 
[[RFC 6750]]
は
[CODE[Bearer]]
の
[[credentials]]
として
[CODE[b64token]]
と称する構文を規定しています。
これは 
[[MIME]] の [[Base64]]
とは矛盾しないという程度の構文上の制約で、若干の拡張も施されています。
構文の定義としてそうなっているだけで、
[[Base64]] 
によるデータであることは求めていません。
(「b64」という名前で暗示しているだけで、 [[Base64]]
に言及すらしていません。)
[SEE[ [[Bearer]] ]]



[268] [[RFC 8030]] [CODE[Topic:]] [[HTTPヘッダー]]は、
構文の制約を [[RFC 4648]] [[base64url]]
により定めています。[[字母]]の定義として参照しているだけで、
それが実際に [[base64url]] で符号化されたデータであることは要求していません。



* uuencode 風表現

[3] [[MIME]] 以外の場面でファイルを貼り付けるのに、 [[uuencode]]
みたいな書き方をすることがあるみたい。

例1:
[PRE(example)[
begin-base64 644 base64ed.data
[INS[... base64 stream ...]]
====
]PRE]

[26] 例2:
[PRE(example)[
begin-base64 644 code.tgz
[INS[... base64 stream ...]]
=
]PRE]

* 実装

[193] [[Base64]] の実装の選択時には、利用したいのがどのバリエーションで、
実装が対応しているのがどのバリエーションであるのかを慎重に検討する必要があります。

[8] [[uuencode]] も[[64進数]]であることを利用して、 uuencode
で符号化した後に [CODE[[[tr]]]] を使うという方法が使われることもあります。

** Perl

[4] [[Perl]] なら、 [CODE(perl)[[[MIME::Base64]]]] を使うのが気楽かと。
Perl 5.7.3 以降では標準で入っています。

[192] 但し、 >>2, >>7 のような変種には対応していません。

** [CODE[base64]] コマンド

[68] 一般的な [[Linux]] 環境では、 [CODE[base64]] コマンドが用意されています。

[69] [[オプション]]なしで実行すると、[[標準入力]]を[[符号化]]し、
結果を[[標準出力]]に書き込みます。

;; [71] [CODE[echo]] [[コマンド]]は [CODE[-n]] オプションなしで実行すると最後に自動的に[[改行]]を付加するので、組み合わせて使う時は注意しないといけません。

[70] [CODE[-d]] [[オプション]]つきで実行すると、[[標準入力]]を[[復号]]し、
結果を[[標準出力]]に書き込みます。

** BASE64.ASM

[FIG[
[PRE(code)[
	ASSUME	CS:CODE,DS:CODE
CODE	SEGMENT

	ORG	100H
START:	MOV	BX,0
START1:	MOV	DI,0
LOOP1:	PUSH	BX
	PUSH	DI
	MOV	AH,06H
	MOV	DL,0FFH
	INT	21H
	POP	DI
	POP	BX
	JNZ	JUMP1
	CMP	DI,0
	JZ	END1
	CMP	DI,1
	JZ	END2
	CMP	DI,2
	JZ	END3
JUMP1:	MOV	BUFFER[DI],AL
	INC	DI
	CMP	DI,3
	JNZ	LOOP1

SHORI2:	MOV	CH,4
LOOP3:	MOV	CL,6
	MOV	SI,0
LOOP2:	SAL	BUFFER+2,1
	RCL	BUFFER+1,1
	RCL	BUFFER+0,1
	RCL	SI,1
	DEC	CL
	JNZ	LOOP2
	PUSH	BX
	PUSH	DI
	PUSH	SI
	PUSH	CX
	MOV	DL,BASE64[SI]
	MOV	AH,06H
	INT	21H
	POP	CX
	POP	SI
	POP	DI
	POP	BX
	DEC	CH
	JNZ	LOOP3
	ADD	BX,DI
	CMP	BX,57
	JNZ	START1
	PUSH	BX
	PUSH	CX
	PUSH	DI
	PUSH	SI
	MOV	DL,0AH
	MOV	AH,06H
	INT	21H
	MOV	DL,0DH
	MOV	AH,06H
	INT	21H
	POP	SI
	POP	DI
	POP	CX
	POP	BX
	JMP	START

END2:	MOV	CH,2
	JMP	LOOP5
END3:	MOV	CH,3
LOOP5:	MOV	CL,6
	MOV	SI,0
LOOP4:	SAL	BUFFER+2,1
	RCL	BUFFER+1,1
	RCL	BUFFER+0,1
	RCL	SI,1
	DEC	CL
	JNZ	LOOP4
	PUSH	CX
	PUSH	DI
	PUSH	SI
	MOV	DL,BASE64[SI]
	MOV	AH,06H
	INT	21H
	POP	SI
	POP	DI
	POP	CX
	DEC	CH
	JNZ	LOOP5
	CMP	DI,2
	JZ	JUMP2
	MOV	DL,'='
	MOV	AH,06H
	INT	21H
JUMP2:	MOV	DL,'='
	MOV	AH,06H
	INT	21H

;処理終了
END1:	MOV	AH,4CH
	MOV	AL,00H
	INT	21H

;base64 moji hyoji
	MOV	AH,09H
	MOV	DX,OFFSET BASE64
	INT	21H

BASE64	DB	'ABCDEFGHIJKLMNOP'
[PRE[
	DB	'QRSTUVWXYZabcdef'
	DB	'ghijklmnopqrstuv'
	DB	'wxyz0123456789+/'
BUFFER	DB	'000','$'

CODE	ENDS
	END	START
]PRE]

[FIGCAPTION[
[52] [CODE[BASE64.ASM]]
[[名無しさん]] [TIME[2007-05-30 05:16:55 +00:00]]
]FIGCAPTION]
]FIG]

* テスト

[223] [CITE@en[tests-web/base64 at master · wakaba/tests-web]] ([TIME[2018-02-04 18:16:57 +09:00]]) <https://github.com/wakaba/tests-web/tree/master/base64>

[40] [CITE@en[RFC 4648 - The Base16, Base32, and Base64 Data Encodings]] ([TIME[2018-01-28 17:12:45 +09:00]]) <https://tools.ietf.org/html/rfc4648#section-10>

[130] [CITE@en[web-platform-tests/base64.json at master · w3c/web-platform-tests]]
([TIME[2018-02-03 18:33:16 +09:00]])
<https://github.com/w3c/web-platform-tests/blob/master/fetch/data-urls/resources/base64.json>

[131] [CITE@en[mime-base64/base64.t at master · gisle/mime-base64]]
([TIME[2018-02-03 18:36:40 +09:00]])
<https://github.com/gisle/mime-base64/blob/master/t/base64.t>

[132] [CITE@en[mime-base64/base64url.t at master · gisle/mime-base64]]
([TIME[2018-02-03 18:36:54 +09:00]])
<https://github.com/gisle/mime-base64/blob/master/t/base64url.t>

[133] [CITE@en[base64url/tests.txt at master · ptarjan/base64url]]
([TIME[2018-02-03 18:37:08 +09:00]])
<https://github.com/ptarjan/base64url/blob/master/tests.txt>

[121] [CITE@en[rust-base64/tests at master · alicemaz/rust-base64]] ([TIME[2018-02-04 16:53:11 +09:00]]) <https://github.com/alicemaz/rust-base64/tree/master/tests>

[218] [CITE@en[tests/base64.c · master · gnutls / GnuTLS · GitLab]] ([TIME[2018-02-04 16:55:57 +09:00]]) <https://gitlab.com/gnutls/gnutls/blob/master/tests/base64.c>

[219] [CITE[org.bouncycastle.util.encoders: Base64Test.java]] ([TIME[2009-06-20 10:24:43 +09:00]]) <http://www.docjar.org/html/api/org/bouncycastle/util/encoders/Base64Test.java.html>

[222] [CITE@en[base64_url/base64_url_spec.rb at master · infopark/base64_url]] ([TIME[2018-02-04 17:19:15 +09:00]]) <https://github.com/infopark/base64_url/blob/master/base64_url_spec.rb>

* 安全性に関して

[34] '''秘密情報送信のための使用''':
[[HTTP]] の[[認証]]や [[SASL]] などでは、[[合言葉]]などの繊細な情報を送信するために
Base64 を使うことがあります。 Base64 
は[[転送符号化]]であって[[暗号化]]では''ありません''が、
第3者 [WEAK[(例えばシステムの管理者)]] 
が繊細な情報を含むメッセージを見てしまったとしても読むことができません
[WEAK[(流石に脳内で Base64 を復号できる猛者はいないでしょう)]]。
もちろん、悪意のある人は計算機を使って復号してしまうでしょうから、
それに対する効果はありません。

[35] '''バッファ溢れ攻撃''': 不正な (字母に含まれない)
文字や末尾以外にある詰めの [CODE(char)[=]]
への対処がいい加減だと、バッファ溢れ攻撃に使われることがあり得ます。
[SRC[[[RFC 3920]] 14.9 など]]

* 関連

[65] [[Base64]] が普及する前は、同じく[[64進数]]でもある [[uuencode]] がよく使われていました。

[194] [[PEM]] や [[MIME]] が当時一般的だった [[uuencode]] ではなく
[[Base64]] を採用したのは、 [[EBCDIC]] や[[ISO/IEC 646の版]]を採用する[[メール]]システムでも問題が起こらないという要件があったためのようです。

[195] しかし当時マイナーだった [[Base64]] を選択したことは、
[[MIME]] の普及の足を引っ張ることになりました。
[[インターネットメール]]や [[Usenet]] の[[ファイル]]転送にはその後も [[uuencode]]
が使われ続け、[TIME[2000年][year:2000]]を過ぎても [[MUA]]
によっては[[添付ファイル]]を [[MIME]] 形式と [[uuencode]] 形式のどちらで送信するか選択するオプションが付いていたくらいです。
受信は両方に対応する必要がありました。 [[MIME]] 未対応の [[MUA]]
でも対応済みの [[MUA]] でも適切に処理できるよう、 [[uuencode]] を非公式に
[[MIME]] の [[CTE]] として実装した [[MUA]] もありました。

-*-*-

[14] 
[[MIME]] の [CODE(MIME)[[[application/octet-stream]]]] 
では、[[オクテット]] (8[[ビット]]) 単位でないビット列も扱うことが出来ます。
そのような場合には全体長が8の倍数になるようにビット [CODE[0]] を詰め、
詰めた数を引数でメモっておきます。

* 歴史


[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]] 
でしか使えない環境依存だから入れたくないのかもしれんが。)

[37]
[[XML]] [[デジタル署名]]系仕様では
[[Base64]] を使うことを識別するために
[CODE(URI)[[[http://www.w3.org/2000/09/xmldsig#base64]]]]
という [[URI参照]]を使っています。
([[名無しさん]] [sage])

[41]
[CITE[たっぴ (パソコン質問掲示板) - Question and Answers -]] <http://pcq.furu.org/thread.php?thread=81003>

> BASE64への変換(エンコード)やBASE64からの逆変換(デコード)はこちらで確認することができるようです。
http://suika.fam.cx/~wakaba/-temp/wiki/wiki?Base64 

ちょ[AA(fw)[wwwwwwwwwwwwwwwwwwwwwwwwwww]] そんな話聞いたことないって[AA(fw)[www]]
([[名無しさん]] [WEAK[2006-05-28 11:09:01 +00:00]])

[51]
[[MTOM]] は、[[往復変換]]を保障するため、 [[XML Schema]]
の [CODE(XML)@en[[[base64Binary]]]] の[[正準形]]のみを最適化対象としています。
([[名無しさん]])

[42]
[CITE[Base64 - Wikipedia, the free encyclopedia]] <http://en.wikipedia.org/wiki/Base64>
([[名無しさん]] [TIME[2006-06-11 00:06:34 +00:00]])

** Web Base64 API の標準化

[REFS[
- [869] [CITE[atob()/btoa() tests]]
([TIME[2011-01-07 14:45:31 +09:00]] 版)
<http://dvcs.w3.org/hg/html/raw-file/tip/tests/submission/AryehGregor/base64.html>
- [870] [CITE['''['''whatwg''']''' Specs for window.atob() and window.btoa()]]
([TIME[2011-01-07 14:10:51 +09:00]] 版)
<http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2011-January/029699.html>
- [871] [CITE[atob/btoa spec WIP]]
([TIME[2011-01-07 05:09:49 +09:00]] 版)
<http://aryeh.name/spec/base64.html>
- [872] [CITE[IRC logs: freenode / #whatwg / 20110102]]
( ([TIME[2011-01-07 23:25:06 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20110102>
- [873] [CITE@en[Web Applications 1.0 r5814      Specify window.atob() and .btoa(). (ack Aryeh for the reverse-engineering to do this)]]
( ([TIME[2011-02-01 17:18:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=5813&to=5814>
- [874] [CITE[''''''[''''''whatwg'''''']'''''' Specs for window.atob() and window.btoa()]]
( ([TIME[2011-02-05 15:12:28 +09:00]] 版))
<http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-February/030154.html>
- [875] [CITE@en[Web Applications 1.0 r5867 remove window.atob/btoa from the W3C draft]]
( ([TIME[2011-02-11 04:45:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=5866&to=5867>
- [876] [CITE@en[Web Applications 1.0 r5874 revert 5867, which was apparently based on a miscommunication]]
( ([TIME[2011-02-12 04:42:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=5873&to=5874>
- [877] [CITE[IRC logs: freenode / #whatwg / 20110211]]
([TIME[2011-02-12 12:58:50 +09:00]] 版)
<http://krijnhoetmer.nl/irc-logs/whatwg/20110211>
- [878] [CITE[IRC logs: freenode / #whatwg / 20110210]]
( ([TIME[2011-03-21 18:25:22 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20110210#l-949>
- [879] [CITE[''''''[''''''whatwg'''''']'''''' Specs for window.atob() and window.btoa()]]
( ([TIME[2011-05-13 23:16:00 +09:00]] 版))
<http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-May/031541.html>
- [880] [CITE@en[Web Applications 1.0 r6874     Change atob() to ignore whitespace. This is a potentially breaking change, but Opera has implemented it for a while and doesn't seem to have had any problems resulting.]]
( ([TIME[2011-12-15 09:44:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=6873&to=6874>
- [868] [CITE[''''''[''''''whatwg'''''']'''''' BinaryEncoding for Typed Arrays using window.btoa and window.atob]]
( ([TIME[2013-08-05 16:18:46 +09:00]] 版))
<http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-August/040364.html>
]REFS]

**

[FIG(amazon)[
Base64
]FIG]

[825] [CITE@en[RFC 6120 - Extensible Messaging and Presence Protocol (XMPP): Core]]
( ([TIME[2011-03-31 08:23:45 +09:00]] 版))
<http://tools.ietf.org/html/rfc6120#section-13.9.1>

[852] [CITE@EN[W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes]]
( ([TIME[2012-04-05 06:34:51 +09:00]] 版))
<http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/#base64Binary>

[854] [CITE[Jakarta Commons Codec による Base64符号の末尾に改行が付加される件について - keigoiの日記]]
( ([TIME[2013-09-30 01:27:44 +09:00]] 版))
<http://d.hatena.ne.jp/keigoi/20090820/1250760023>

[855] [CITE@ja[Base 64 エンコーディングと改行 (line feed) の話 - ひだまりソケットは壊れない]]
( ([TIME[2013-09-30 01:27:54 +09:00]] 版))
<http://vividcode.hatenablog.com/entry/2012/05/12/051058#comment-11696248318757556925>

[856] [CITE@en[RFC 6591 - Authentication Failure Reporting Using the Abuse Reporting Format]]
( ([TIME[2013-08-11 08:35:52 +09:00]] 版))
<http://tools.ietf.org/html/rfc6591#section-2.3>


[881] [CITE@EN[XPath and XQuery Functions and Operators 3.0]]
( ([TIME[2014-04-08 07:02:07 +09:00]] 版))
<http://www.w3.org/TR/xpath-functions-3/#binary-functions>

[882] [CITE[Native base64 utility methods]]
( ([TIME[2014-05-07 17:16:24 +09:00]] 版))
<http://esdiscuss.org/topic/native-base64-utility-methods>

[883] [CITE[IRC logs: freenode / #whatwg / 20140505]]
( ([TIME[2014-05-07 17:15:03 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140505#l-183>

[885] [CITE@en[Bug 22731 – Should atob() trim spaces, or not?]]
( ([TIME[2014-09-28 09:05:00 +09:00]] 版))
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=22731>

[886] [CITE[IRC logs: freenode / #whatwg / 20140929]]
( ([TIME[2014-09-30 01:12:07 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140929#l-683>

[887] [CITE[IRC logs: freenode / #whatwg / 20140929]]
( ([TIME[2014-09-30 01:12:14 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140929#l-683>

[888] [CITE@en[RFC 989 - Privacy enhancement for Internet electronic mail: Part I: Message encipherment and authentication procedures]]
( ([TIME[2014-08-11 06:19:13 +09:00]] 版))
<https://tools.ietf.org/html/rfc989>

[FIG(quote)[
[FIGCAPTION[
[38] [CITE@en[RFC 989 - Privacy enhancement for Internet electronic mail: Part I: Message encipherment and authentication procedures]]
([TIME[2015-02-22 16:43:49 +09:00]] 版)
<https://tools.ietf.org/html/rfc989#section-4.4>
]FIGCAPTION]

> A specific point regarding the integration of privacy-enhanced mail
>    facilities with the message encapsulation mechanism is worthy of
>    note.  The subset of IA5 selected for transmission encoding
>    intentionally excludes the character "-", so encapsulated text can be
>    distinguished unambiguously from a message's closing encapsulation
>    boundary (Post-EB) without recourse to character stuffing.

]FIG]

[48] [CITE@en[RFC 2440 - OpenPGP Message Format]]
([TIME[2015-02-15 14:39:41 +09:00]] 版)
<https://tools.ietf.org/html/rfc2440#section-6.3>

[49] [CITE@en[RFC 4880 - OpenPGP Message Format]]
([TIME[2015-04-05 14:41:03 +09:00]] 版)
<https://tools.ietf.org/html/rfc4880#section-6>

[50] [CITE@en[RFC 1113 - Privacy enhancement for Internet electronic mail: Part I - message encipherment and authentication procedures]]
([TIME[2015-03-22 21:14:51 +09:00]] 版)
<http://tools.ietf.org/html/rfc1113#section-4.3>

[FIG(quote)[
[FIGCAPTION[
[53] [CITE[RFC Errata Report]]
([TIME[2015-05-16 22:22:26 +09:00]] 版)
<http://www.rfc-editor.org/errata_search.php?rfc=6455>
]FIGCAPTION]

> The "test vector" for Sec-WebSocket-Key encoding, provided in RFC 6455 section 4.1, is wrong. It was processed by a base 64 encoder that was "improperly implemented" as mentioned in RFC 4648 section 3.5. Pad bits were not set to zero, which is a "MUST" requirement in RFC 4648,

]FIG]




[57] [CITE@ja[Base 64 エンコーディングと改行 (line feed) の話 - ひだまりソケットは壊れない]]
([TIME[2015-10-02 23:12:45 +09:00]] 版)
<http://vividcode.hatenablog.com/entry/2012/05/12/051058>

[59] [CITE[Base64 って結構カオス? - DELPHIER@はてな]]
([TIME[2015-06-14 14:00:53 +09:00]] 版)
<http://d.hatena.ne.jp/izariuo440/20110127/1296138201>


[62] [CITE@en[Editorial: put properties shared across globals on mixin · whatwg/html@cdd48e1]]
([TIME[2016-04-07 20:03:43 +09:00]] 版)
<https://github.com/whatwg/html/commit/cdd48e1f570c817402bf62108847c4a9f4b00b1e>

[FIG(quote)[
[FIGCAPTION[
[64] [CITE@en[Encoded Polyline Algorithm Format  |  Google Maps APIs  |  Google Developers]]
([TIME[2016-07-13 06:14:37 +09:00]])
<https://developers.google.com/maps/documentation/utilities/polylinealgorithm>
]FIGCAPTION]

> The encoding process converts a binary value into a series of character codes for ASCII characters using the familiar base64 encoding scheme

]FIG]




[76] [CITE@EN[XPath and XQuery Functions and Operators 3.1]]
([TIME[2017-03-21 16:02:06 +09:00]])
<https://www.w3.org/TR/2017/REC-xpath-functions-31-20170321/#func-base64Binary-equal>

** Web Base64 の標準化

[77] [CITE@en[Ambiguities in the "data" URL scheme]]
([TIME[2014-11-11 20:05:54 +09:00]])
<https://simonsapin.github.io/data-urls/>

[78] [CITE@en[Define forgiving base64]]
([[annevk]]著, [TIME[2017-08-16 01:12:22 +09:00]])
<https://github.com/whatwg/infra/commit/6c69d4505476eb6adf08f3c17f682cff7f58ccb2>

[79] [CITE@en[base64: move code point check back down]]
([[annevk]]著, [TIME[2017-08-16 19:15:13 +09:00]])
<https://github.com/whatwg/infra/commit/6509cfbbf0c47020f8bcd0ce9786eea0b4f4bb74>

[80] [CITE@en[Define forgiving-base64 by annevk · Pull Request #145 · whatwg/infra]]
([TIME[2017-08-24 17:04:32 +09:00]])
<https://github.com/whatwg/infra/pull/145>

[81] [CITE@en[base64: move code point check back down by annevk · Pull Request #147 · whatwg/infra]]
([TIME[2017-08-24 17:06:39 +09:00]])
<https://github.com/whatwg/infra/pull/147>

[82] [CITE@en[base64: move code point check back down]]
([[annevk]]著, [TIME[2017-08-16 19:15:13 +09:00]])
<https://github.com/whatwg/infra/commit/6509cfbbf0c47020f8bcd0ce9786eea0b4f4bb74>

[83] [CITE@en[Move base64 algorithms to Infra by annevk · Pull Request #2920 · whatwg/html]]
([TIME[2017-08-24 17:07:36 +09:00]])
<https://github.com/whatwg/html/pull/2920>

[84] [CITE@en[Where should the web platform's base64 algorithm go? · Issue #2912 · whatwg/html]]
([TIME[2017-08-24 17:08:48 +09:00]])
<https://github.com/whatwg/html/issues/2912>

[85] [CITE@en[Move base64 algorithms to Infra]]
([[annevk]]著, [TIME[2017-08-15 17:55:04 +09:00]])
<https://github.com/whatwg/html/commit/9008ac9439aa7e4a30bd34ace8f7a2f1e63c153c>

[127] [CITE@en[Define data: URLs by annevk · Pull Request #579 · whatwg/fetch]]
([TIME[2018-02-01 23:20:32 +09:00]])
<https://github.com/whatwg/fetch/pull/579>

[128] [CITE@en[web-platform-tests/html/webappapis/atob at master · w3c/web-platform-tests]]
([TIME[2018-02-03 18:27:59 +09:00]])
<https://github.com/w3c/web-platform-tests/tree/master/html/webappapis/atob>

[129] [CITE@en[data: URL processing and generalized forgiving-base64 decode tests]]
([[annevk]]著, [TIME[2018-01-31 17:57:21 +09:00]])
<https://github.com/w3c/web-platform-tests/commit/7eec2bf5e522d28d99ced501b0f49477c3b105d5>

**

[FIG(quote)[
[FIGCAPTION[
[134] [CITE@en[ptarjan/base64url: Various language implementations of base64_url_decode]]
([TIME[2018-02-03 18:37:27 +09:00]])
<https://github.com/ptarjan/base64url>
]FIGCAPTION]

> Some simple samples of doing base64 url decoding. 

]FIG]


[FIG(quote)[
[FIGCAPTION[
[226] ([TIME[2018-02-09 09:49:38 +09:00]])
<https://info.quantcast.com/rs/516-DGM-318/images/Framework%20Vendor%20List%20%26%20Cookie%20Format%20Specification.pdf>
]FIGCAPTION]

> Base64-encoding of
> the concatenated
> Cookie Value Fields
> bits described below
> The binary bits should be padded at the
> end with zeroes to the nearest multiple of
> 8 bits, packed into a string of bytes, and
> have websafe-base64 encoding
> performed.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[227] ([TIME[2018-02-09 09:49:38 +09:00]])
<https://info.quantcast.com/rs/516-DGM-318/images/Framework%20Vendor%20List%20%26%20Cookie%20Format%20Specification.pdf>
]FIGCAPTION]

> Above fields are multiples of 6 bits to fit
> into base64-encoded bytes.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[228] [CITE@en[Concise Binary Object Representation (CBOR)]]
([TIME[2018-02-23 07:30:37 +09:00]])
<https://cbor-wg.github.io/CBORbis/#encodedtext>
]FIGCAPTION]

> Tags 33 and 34 are for base64url- and base64-encoded text strings, as defined in '''['''RFC4648''']''';

]FIG]


[230] [CITE@en[Correct variable name in base64 algorithm]]
([[annevk]]著, [TIME[2018-04-17 20:34:50 +09:00]])
<https://github.com/whatwg/infra/commit/fcacad00d2b34fbc7ae1d023e81e9661f46e4b0d>

[231] [CITE@en[Correct variable name in base64 algorithm by annevk · Pull Request #195 · whatwg/infra]]
([TIME[2018-04-18 13:27:57 +09:00]])
<https://github.com/whatwg/infra/pull/195>

[FIG(quote)[
[FIGCAPTION[
[232] [CITE@en[Language Guide (proto3)  |  Protocol Buffers  |  Google Developers]]
([TIME[2018-04-07 03:12:07 +09:00]])
<https://developers.google.com/protocol-buffers/docs/proto3#json>
]FIGCAPTION]

> JSON value will be the data encoded as a string using standard base64 encoding with paddings. Either standard or URL-safe base64 encoding with/without paddings are accepted.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[260] [CITE@en[Enc - OpenSSLWiki]]
([TIME[2018-10-08 14:03:10 +09:00]])
<https://wiki.openssl.org/index.php/Enc#Options>
]FIGCAPTION]

> By default the encoded file has a line break every 64 characters. To suppress this you can use in addition to -base64 the -A flag. This will produce a file with no line breaks at all.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[261] [CITE@en[Base64 - OpenSSLWiki]]
([TIME[2017-11-23 21:14:39 +09:00]])
<https://wiki.openssl.org/index.php/Base64>
]FIGCAPTION]

> Base64 itself does not impose a line split, but openssl uses it in PEM context hence enforce that base64 content is splitted by lines with a maximum of 80 characters.

]FIG]


[271] [CITE@en[Decentralized Identifiers (DIDs) v1.0]]
([TIME[2020-12-27T18:27:35.000Z]], [TIME[2020-12-29T05:33:31.702Z]])
<https://w3c.github.io/did-core/#cbor-extensibility>


[272] [CITE@en[draft-multiformats-multibase-02 - The Multibase Data Format]], [TIME[2020-12-21T02:06:34.000Z]], [TIME[2020-12-29T05:52:41.555Z]] <https://tools.ietf.org/html/draft-multiformats-multibase-02>


[FIG(quote)[
[FIGCAPTION[
[275] [CITE[カスタムポリシーを使用する署名付き Cookie の設定 - Amazon CloudFront]]
([TIME[2021-04-15 22:07:50 +09:00]])
<https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html#private-content-custom-policy-signature-cookies>
]FIGCAPTION]

> MIME base64 エンコーディングを使用して文字列を Base64 エンコードします。詳細については、RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies の Section 6.8, Base64 Content-Transfer-Encoding を参照してください。
> URL クエリ文字列内の無効な文字を有効な文字で置き換えます。次の表に無効な文字と有効な文字を示します。
> 無効な文字 (置換元)	有効な文字 (置換先)
> +
> - (ハイフン)
> =
> _ (下線)
> /
> ~ (チルダ)

]FIG]


[289] [CITE@en[base64 dialect · Issue #539 · httpwg/http-extensions]]
([TIME[2021-06-29T02:25:57.000Z]])
<https://github.com/httpwg/http-extensions/issues/539>

[291] [CITE@en[d3x0r/JSOX: JavaScript Object eXchange format; extended JSON/JSON6]]
([TIME[2021-10-04T08:33:36.000Z]])
<https://github.com/d3x0r/JSOX#base64-character-set>

[298] [CITE@en[How does the base64 chosen here compare to atob/btoa? · Issue #5 · tc39/proposal-arraybuffer-base64 · GitHub]], [TIME[2023-06-26T05:16:50.000Z]] <https://github.com/tc39/proposal-arraybuffer-base64/issues/5>

