Ascii85 をエンコード・デコードする手順
- テキストを 入力 · テキスト に入力するか貼り付けます。出力 · Ascii85(Adobe) に Ascii85 が表示されます。
- 出力の下で、PostScript/PDF の枠組みにするなら <~ ~> 区切りを付ける にチェックを入れ、デコーダーが短縮表記に対応していないなら ゼロのグループを z で表す のチェックを外します。
- 別の Base85 アルファベットを使うには、変換先 を Base85(Git/Python b85)、Z85(ZeroMQ)、RFC 1924(IPv6 Base85) のいずれかに変えます。
- デコードするには、方向の切り替えで Ascii85(Adobe) → テキスト をクリックします。デコーダーは
<~ ~>区切り、z、y、あらゆる空白を受け付けるので、ファイルから取った改行入りのデータもそのまま貼り付けられます。 - 結果がバイナリなら、変換先 を Hex(16進数) にするか、バイトを保存 をクリックします。
Ascii85 の仕組み
Ascii85 は 4 バイトずつ取り出し、それを 1 つの 32 ビットのビッグエンディアンの数として読み、85 進数の 5 桁で書きます。各桁は !(値 0)から u(値 84)までの文字です。4 バイトに 5 文字なのでオーバーヘッドは 25% で、Base64 の 33% より小さくなります。
古典的な例は Man (末尾に空白あり)で、バイト列 4d 61 6e 20 は 9jqo^ になります。最後のグループが足りないときは、エンコーダーがゼロバイトで埋め、n バイトに対して n + 1 文字だけを書きます。そのため Hello(5 バイト)は 87cURDZ になります。Hell の 5 文字と o の 2 文字です。
よく現れるパターンを短くする短縮表記が 2 つあります。z は 4 つのゼロバイトのグループ(そのまま書くと !!!!!)を置き換えます。y は btoa 版で 4 つの空白を置き換えます。このデコーダーはどちらも読み、エンコーダーは z を書きます(切り替え可能)が、y は書きません。
Base85 のバリアント比較
| バリアント | アルファベット | Hello | 使われている場所 |
|---|---|---|---|
| Ascii85(Adobe) | ASCII 順で ! から u | 87cURDZ | PostScript、PDF の /ASCII85Decode |
| Base85(Git / Python) | 0-9 A-Z a-z !#$%&()*+-;<=>?@^_`{|}~ | NM&qnZv | Git のバイナリパッチ、Python の base64.b85encode |
| Z85 | 0-9 a-z A-Z .-:+=^!/*?&<>()[]{}@%$# | nm=QNzV | ZeroMQ と CurveZMQ の鍵。Z85 を参照 |
| RFC 1924 | Git と同じ | IPv6 アドレス 1 つで 4)+k&C#VzJ4br>0wv%Yp | IPv6 アドレス(ジョークとして) |
Git と RFC 1924 のアルファベットは同じですが、RFC 1924 は 16 バイトのアドレス全体を、4 バイトのグループ 4 つではなく 1 つの 128 ビットの数として扱います。RFC 1924 は 1996 年 4 月 1 日に公開されたもので、1080::8:800:200c:417a を 4)+k&C#VzJ4br>0wv%Yp と書くことを提案しています。変換ツールで 変換元 を IPv6 アドレス、変換先 を RFC 1924(IPv6 Base85) にすると再現できます。
PDF と PostScript の Ascii85
Ascii85 は PostScript Level 2 で、画像やフォントなどのバイナリデータをテキストファイルに埋め込むために導入されました。データは <~ … ~> で囲まれます。PDF では、/Filter /ASCII85Decode のストリームが同じエンコーディングを使い、~> で終わります。ここのデコーダーは、先頭の <~ があってもなくても終端マーカーを見つけます。
Ascii85 は、/Filter [/ASCII85Decode /FlateDecode] のようなフィルターの連鎖の外側に置かれることがよくあります。その場合、Ascii85 をデコードして得られるのは読める内容ではなく、zlib で圧縮されたバイト列です。
Git は Base85 を別の形で使います。GIT binary patch では、各行が長さを表す 1 文字(1〜26 バイトなら A–Z、27〜52 バイトなら a–z)で始まり、その後に zlib 圧縮データの Base85 が続きます。デコードする前に各行の先頭の 1 文字を取り除き、結果を展開してください。
Python での Ascii85 と Base85
標準ライブラリに両方のアルファベットがあります。
import base64
base64.a85encode(b"Hello") # b'87cURDZ'
base64.a85encode(b"Hello", adobe=True) # b'<~87cURDZ~>'
base64.a85encode(b" ", foldspaces=True) # b'y'
base64.b85encode(b"Hello") # b'NM&qnZv'
base64.a85decode(b"<~9jqo^~>", adobe=True) # b'Man '
区切りを受け付けるには、a85decode に adobe=True が必要です。エンコードのレシピは Python のページ にもっとあります。
よくある問題
- 「位置 … の z は 5 文字グループの間にしか置けません」。 グループの途中に
zがあります。データが壊れているか、Ascii85 ではありません。Z85 と Git の Base85 では、zは普通の桁の 1 つです。 - 「位置 … から始まるグループが範囲外です」。 5 文字が 2^32 − 1 を超える値を表しています。Git の Base85 や Z85 を Ascii85 としてデコードすると起こります。変換元 を切り替えてください。
v、{、|などの予期しない文字。uより後ろの文字は、yとzの短縮表記を除いてすべて Ascii85 のアルファベットの外にあり、これも別のバリアントである兆候です。- 出力の末尾に余分なゼロバイトが付く。 使ったエンコーダーが最後のグループを埋めて 5 文字すべてを書いています。Ascii85 では、n バイトの最後のグループには n + 1 文字を書きます。
よくある質問
Base85 と Ascii85 の違いは何ですか?
Base85 は、4 バイトを 85 文字の集合から選んだ 5 文字で書くという考え方の総称です。Ascii85 は Adobe 版で、! から u までの文字、z の短縮表記、<~ ~> 区切りを使います。Git、Python の b85encode、Z85、RFC 1924 は、同じ計算を別のアルファベットで行います。
Ascii85 の z は何を意味しますか?
z 1 文字は 4 つのゼロバイトを表し、本来なら !!!!! と書くところを短縮しています。使えるのは 5 文字のグループが始まる位置だけで、グループの途中に z があるとエラーになります。
PDF の Ascii85 をデコードするには?
stream と endstream の間のストリームデータを ~> まで含めてコピーし、方向を Ascii85(Adobe) → テキスト にして貼り付けます。ストリームに /FlateDecode も指定されている場合、結果は zlib データです。変換先 を Base64 にして、gzip・zlib デコーダー で展開してください。
Base85 は Base64 より優れていますか?
約 6% 短くなります。オーバーヘッドは 33% に対して 25% です。ただしバリアントによっては、アルファベットに引用符、バックスラッシュ、< や & が含まれるため、Base64 なら不要な JSON、XML、シェルでのエスケープが必要になります。これらの文字が安全に使える場所で使ってください。