Ascii85
Ascii85[読み疑問点]は、Base85とも称され、Paul E.Rutterにより開発されたバイナリデータを文字列に変換する手法の一種である。4バイトのバイナリデータを符号化し5文字のASCIIコードを用いて文字を表す手法であるため、バイナリデータをAscii85で表す場合はデータ長が5/4に増加する。データ長が4/3になるuuencodeやBase64に比べ効率的である。現代では主にAdobeのPostScriptやPortable Document Formatファイル内で用いられている。
基本的な考え方
バイナリ-テキストエンコーディングは、人間が読めるテキストのみの通信を仮定した通信プロトコルを用いて任意のバイナリデータを送受信するために必要となる。 通信プロトコルで使用可能な文字はASCII制御コードを除いた7ビット文字である(ただし、改行・空白文字は印刷により安全とはいえない)。したがって95種類のASCIIの印刷可能文字が安全に通信できる文字といえる。
4バイトのビット列は232 =4,294,967,296個の値を表現可能である。 そして、85進記数法での5桁の数字は855 =4,437,053,125個の値を表現可能であるため,4バイト=32ビットの値と一意に対応可能である。 845 = 4,182,119,424 < 232であり、4バイトの数を5桁で表現するための最小の整数が85であるため85が基数として選ばれた。
Ascii85への符号化は、まず4バイト毎に1ブロックとしビッグエンディアン方式で符号なし整数と解釈する。 その値を85進記数法で表し、それぞれの桁0〜84の値をASCIIの印刷可能文字である '!'(33)〜 'u'(117)に対応させる。 ただし、効率の良い圧縮のために頻出する全ビットが0であるブロックは "!!!!!" の代わりに 'z' の1文字を用いる。
例えば 'z' が含まれる場合など、復号エラーによって、232 − 1(Ascii85での"s8W-!
")より大きな値が復号される可能性がある。空白文字は行長の制限などにより生じる可能性があるため無視される。
Ascii85の欠点の1つに、バックスラッシュやアポストロフィーのようなエスケープ文字を含む点が存在する。エスケープ文字はプログラミング言語や通信プロトコルにおいて特殊な意味を持つ。Z85のような85を基とした他のエンコーディングではソースコード内に存在しても安全な設計となっている[1]。
変換例
Thomas Hobbes の Leviathan からの引用
- 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.
この文章をAscii85で変換すると以下の文章となる。 ただし "<~" と "~>" は開始と終了を表す
<~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/AKY i(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIa l(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G >uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c~>
変換過程
Text content | M | a | n | ... | s | u | r | e | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ASCII | 77 | 97 | 110 | 32 | ... | 115 | 117 | 114 | 101 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Bit pattern | 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 | ... | 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-bit Value | 1,298,230,816 = 24×854 + 73×853 + 80×852 + 78×85 + 61 | ... | 1,937,076,837 = 37×854 + 9×853 + 17×852 + 44×85 + 22 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Base 85 (+33) | 24 (57) | 73 (106) | 80 (113) | 78 (111) | 61 (94) | ... | 37 (70) | 9 (42) | 17 (50) | 44 (77) | 22 (55) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
ASCII | 9 | j | q | o | ^ | ... | F | * | 2 | M | 7 |
最後の4バイトは対応する文字がない部分があるため、0埋めを行う。 Since the last 4-tuple is incomplete, it must be padded with three zero bytes:
Text content | . | \0 | \0 | \0 | ||||||||||||||||||||||||||||
ASCII | 46 | 0 | 0 | 0 | ||||||||||||||||||||||||||||
Bit pattern | 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-bit Value | 771,751,936 = 14×854 + 66×853 + 56×852 + 74×85 + 46 | |||||||||||||||||||||||||||||||
Base 85 (+33) | 14 (47) | 66 (99) | 56 (89) | 74 (107) | 46 (79) | |||||||||||||||||||||||||||
ASCII | / | c | Y | k | O |
3バイトが0埋めされているため、最後の 'YkO'は出力しない。
復号は逆操作を行う。ただし、最後の5文字だけは 'u' で埋めて計算する。
ASCII | / | c | u | u | u | |||||||||||||||||||||||||||
Base 85 (+33) | 14 (47) | 66 (99) | 84 (117) | 84 (117) | 84 (117) | |||||||||||||||||||||||||||
32-bit Value | 771,955,124 = 14×854 + 66×853 + 84×852 + 84×85 + 84 | |||||||||||||||||||||||||||||||
Bit pattern | 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 |
ASCII | 46 | 3 | 25 | 180 | ||||||||||||||||||||||||||||
Text content | . | [ ETX ] | [ EM ] | ´ (Extended ASCII) |
入力の最後は 'u' で埋めたため、出力の最後の3バイトは無視し、原文のピリオドまでを復号結果とする。 入力に '0' のみのブロックが存在しないため、今回のAscii85では 'z' は現れない。
脚注
出典
- ^ Pieter Hintjens. “32-Z85 · ZeroMQ RFC”. the ZeroMQ RFC project. 2016年12月23日閲覧。