Ascii85 ( Base85とも呼ばれる)は、 Paul E. Rutter がbtoaユーティリティ用に開発したバイナリからテキストへのエンコード方式です。5つのASCII文字で4バイトのバイナリデータを表すため(ASCII 文字あたり8ビットと仮定すると、エンコード後のサイズは元のサイズより1 ⁄ 4大きくなります)、4つの文字で3バイトのデータを表すuuencodeやBase64 (ASCII 文字あたり8ビットと仮定すると、エンコード後のサイズは1 ⁄ 3大きくなります)よりも効率的です。
近年の主な用途としては、AdobeのPostScriptやPortable Document Formatファイル形式、 Gitで使用されるバイナリファイルのパッチエンコーディングなどが挙げられます。[ 1 ]
バイナリからテキストへのエンコードの基本的な必要性は、英語の人間が読めるテキストのみを伝送するために設計された既存の通信プロトコルを介して、任意のバイナリデータを通信する必要があることに起因します。これらの通信プロトコルは7ビットセーフ(かつ、その範囲内で特定のASCII制御コードの使用を回避)であり、一定の最大間隔で改行を必要とする場合や、空白文字を保持しない場合があります。したがって、データの伝送に「安全」に使用できるのは、印刷可能な94文字のASCII文字のみです。
85はnの最小の整数値であり、 n 5 ≥ 256 4 2 32となるため、少なくとも85個の異なるシンボルが利用可能であれば、任意の4バイトシーケンスを5つのシンボルとしてエンコードできます。(基数-85の5桁は、0から4,437,053,124までの整数を表すことができ、これは4,294,967,296通りの4バイトシーケンスすべてを表すのに十分です。)
エンコードされたテキストで使用される文字は!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu、さらにz4 つのゼロ バイトのシーケンスをマークする文字です。
エンコード時には、4バイトの各グループが32ビットの2進数として扱われ、最上位バイトが先頭になります(Ascii85はビッグエンディアン方式を採用しています)。これは、85で繰り返し割り算し、その剰余を求めることで、85を基数とする5桁の数字に変換されます。次に、各桁(これも最上位バイトが先頭)に33を加算することで、ASCII印字可能文字としてエンコードされます。これにより、ASCII文字は33(!)から117(u)までとなります。
すべてゼロのデータは非常に一般的であるため、データ圧縮のために例外が設けられ、すべてゼロのグループはzではなく1 つの文字としてエンコードされます!!!!!。
2 32 − 1を超える値にデコードされる文字のグループ(エンコードではs8W-!)は、デコードエラーを引き起こします。また、zグループ内の文字も同様です。文字間の空白は無視され、行長の制限に合わせて任意の位置に配置できます。
元の仕様では、4 バイトの倍数のストリームのみをエンコードできます。
エンコードされたデータには、多くのプログラミング言語や一部のテキストベースプロトコルにおいて特別な意味を持つ文字(左山括弧<、バックスラッシュ\、一重引用符と二重引用符'&など)が含まれる場合があります。Z85やRFC 1924"などの他のBase85エンコードは、ソースコード内で安全に使用できるように設計されています。[ 2 ]
オリジナルのbtoaプログラムは、常に完全なグループをエンコードし(必要に応じてソースをパディングします)、プレフィックス行に「xbtoa Begin」、サフィックス行に「xbtoa End」、そして元のファイル長(10進数と16進数)と3つの32ビットチェックサムを付加します。デコーダーは、グループの長さがパディングされている量を判断するためにファイル長を使用する必要があります。btoaエンコードの当初の提案では、ASCIIスペース文字から「t」までのエンコードアルファベットが使用されていましたが、「一部のメーラーで問題が発生する(末尾の空白文字が削除される)」ため、「!」から「u」までのエンコードアルファベットに置き換えられました。[ 3 ]このプログラムは、すべてゼロのグループを表す特別な短縮形「 」も導入しました。バージョン4.2では、すべてASCIIスペース文字(0x20202020)のグループを表すz「 」例外が追加されました。 y
「ZMODEM Pack-7エンコーディング」は、4オクテットのグループを5つの印刷可能なASCII文字のグループにエンコードします。これはAscii85と類似、あるいはおそらく同じ方法です。ZMODEMプログラムが、圧縮済みの8ビットデータファイルを7ビットデータチャネルで送信する場合、「ZMODEM Pack-7エンコーディング」が使用されます。[ 4 ]
Adobe は基本的な btoa エンコードを採用しましたが、若干の変更を加えて Ascii85 と名付けました。使用される文字は ASCII 文字 33 ( !) から 117 ( u) まで (基数 85 の数字 0 から 84 を表す) と文字z(32 ビットの 0 値を表す特別なケース) で、空白は無視されます。Adobe は、~>Ascii85 エンコードされた文字列の終わりを示すために区切り文字 " " を使用し、文字列の先頭に " <~" を付けることもできます。[ 5 ] Adobe では、最後のグループを切り捨てることで長さを表します。ソース バイトの最後のブロックに含まれるバイト数が 4 バイト未満の場合、エンコード前にブロックに最大 3 つの null バイトが埋め込まれます。エンコード後、埋め込みとして追加されたバイトと同じ数のバイトが出力の末尾から削除されます。
デコード時には逆の手順が適用されます。つまり、最後のブロックは Ascii85 文字で 5 バイトにパディングされu、パディングとして追加されたバイト数分が出力の末尾から省略されます (例を参照)。
パディングは任意ではありません。バイナリからBase64への変換は、ビットの再グループ化のみを行い、ビット自体やその順序は変更しません(バイナリの上位ビットは、Base64表現の下位ビットに影響を与えません)。バイナリ数をBase85(85は2の累乗ではありません)に変換する場合、上位ビットはBase85の下位桁に影響を与え、その逆も同様です。エンコード時にバイナリの下位ビット(ゼロビット)をパディングし、uデコード時にBase85の上位ビット(s)をパディングすることで、上位ビットが確実に保持されます(バイナリのゼロパディングによって十分な余裕が確保されるため、小さな加算はトラップされ、上位ビットへの「繰り上がり」は発生しません)。
Ascii85 でエンコードされたブロックでは、5 文字のブロックの途中を含む任意の場所に空白文字と改行文字が存在する可能性がありますが、それらは黙って無視される必要があります。
Adobe の仕様では、btoa のy例外はサポートされていません。
トーマス・ホッブスの『リヴァイアサン』からの引用です。
Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.
269文字の引用符がUS-ASCIIまたは100%互換のエンコードで提供され、それをAscii85で次の337文字として再エンコードできると仮定します(カウントと出力は、前後の接尾辞「<~」と「 」なしで示されています~>)。[ a ]
9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,O< DJ+*.@<*K0@<6L(Df-\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKYi( DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIal( DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G>u D.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c
再エンコードの詳細については、ホッブスの引用の冒頭をご覧ください。
| テキストコンテンツ | M | 1つの | n | ... | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| アスキー | 77 (0x4d) | 97 (0x61) | 110 (0x6e) | 32 (0x20) | ... | ||||||||||||||||||||||||||||
| ビットパターン | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | ... |
| 32ビット値 | 1,298,230,816 = 24×85 4 + 73×85 3 + 80×85 2 + 78×85 + 61 | ... | |||||||||||||||||||||||||||||||
| ベース85(+33) | 24 (57) | 73 (106) | 80 (113) | 78 (111) | 61 (94) | ... | |||||||||||||||||||||||||||
| アスキー | 9 | j | q | o | ^ | ... | |||||||||||||||||||||||||||
...そして以下は引用の終わりです(最後から2番目の4つのタプル):
| テキストコンテンツ | s | あなた | r | e | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| アスキー | 115 (0x73) | 117 (0x75) | 114 (0x72) | 101 (0x65) | ||||||||||||||||||||||||||||
| ビットパターン | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 |
| 32ビット値 | 1,937,076,837 = 37×85 4 + 9×85 3 + 17×85 2 + 44×85 + 22 | |||||||||||||||||||||||||||||||
| ベース85(+33) | 37 (70) | 9 (42) | 17 (50) | 44 (77) | 22 (55) | |||||||||||||||||||||||||||
| アスキー | F | * | 2 | M | 7 | |||||||||||||||||||||||||||
ただし、最後の 4 タプルはピリオドの後で不完全なので、3 つのゼロ バイトを埋め込む必要があります。
| テキストコンテンツ | 。 | \0 | \0 | \0 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| アスキー | 46 (0x2e) | 0 (0x00) | 0 (0x00) | 0 (0x00) | ||||||||||||||||||||||||||||
| ビットパターン | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 32ビット値 | 771,751,936 = 14×85 4 + 66×85 3 + 56×85 2 + 74×85 + 46 | |||||||||||||||||||||||||||||||
| ベース85(+33) | 14 (47) | 66 (99) | 56 (89) | 74 (107) | 46 (79) | |||||||||||||||||||||||||||
| アスキー | / | c | ||||||||||||||||||||||||||||||
3 バイトのパディングを追加する必要があったため、最後の 3 つの文字「YkO」は出力から省略されます。
デコードは逆に行われますが、最後の 5 タプルには 'u' 文字が埋め込まれます。
| アスキー | / | c | あなた | あなた | あなた | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ベース85(+33) | 14 (47) | 66 (99) | 84 (117) | 84 (117) | 84 (117) | |||||||||||||||||||||||||||
| 32ビット値 | 771,955,124 = 14×85 4 + 66×85 3 + 84×85 2 + 84×85 + 84 | |||||||||||||||||||||||||||||||
| ビットパターン | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
| アスキー | 46 | 3 | 25 | 180 | ||||||||||||||||||||||||||||
| テキストコンテンツ | 。 | [ ETX ] | [ EM ] | ´ (拡張ASCII ) | ||||||||||||||||||||||||||||
入力には 3 つの「u」バイトを埋め込む必要があったため、出力の最後の 3 バイトは無視され、元のピリオドが残ります。
入力文には 4 つの連続するゼロ バイトが含まれていないため、例では 'z' の略語が使用されていません。
Ascii85 エンコーディングは、 Base64よりもオーバーヘッドが少なく、7 ビットおよび 8 ビットのMIMEと互換性があります。
Ascii85 の潜在的な互換性の問題の一つは、Ascii85 が使用する文字の一部がXMLやSGMLなどのマークアップ言語で重要な意味を持つことです。これらの文書に Ascii85 データを含めるには、引用符、山括弧、およびアンパサンドをエスケープする必要がある場合があります。
1996年4月1日に公開された情報提供RFC 1924:「IPv6アドレスのコンパクトな表現」は、ロバート・エルツによるエイプリルフールのジョークとして、IPv6アドレスのbase85エンコードを提案しています。これは、前述の方式とは異なり、異なる85文字のASCII文字セットを提案し、128ビットの数値に対してすべての演算処理を行い、4つの32ビットグループに分割するのではなく、単一の20桁のbase85数値(内部の空白は許可されません)に変換することを提案しています。
提案されている文字セットは、順に、0– 9、A– Z、a– z、そして 23 文字です!#$%&()*+-;<=>?@^_`{|}~。表現可能な最大のアドレス、2 128 −1 = 74×85 19 + 53×85 18 + 5×85 17 + ... は としてエンコードされます=r54lj&NUUO~Hi%c2ym0。
この文字セットは文字 を除外しているため、 JSON文字列(と はエスケープが必要です)"',./:[\] での使用に適しています。ただし、SGMLベースのプロトコル(特にXML)では、 、、に対応するために文字列エスケープが必要になる場合があります。 "\<>&