2014-02-14

Base62のような何か

Base64という規格が標準化され、一般に広く利用されています。Wikipediaによると、

Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式である。

0~9、A~Z、a~z、+、/ の64文字を用いて、バイナリデータ列を、可読な文字列に変換するフォーマットです。

以上は、今さらあえてわざわざ説明するまでもない、お馴染みのことです。

しかし、0~9、A~Z、a~z の62文字、これに加えて + と / の2文字の記号、文字数調整の埋草として = の、合計65種類の文字を使用するため、ある種の用途で不便です。

+ は、URL表現において、空白文字に変換されます。/ はファイルシステムのパス区切り文字として使われます。= も代入演算子として使用される場合に、邪魔な存在となります。

そのため、英数62文字のみを使用して、URLやファイルシステムに影響を与えるような文字を使用せずに、バイナリデータを可読文字列に変換するフォーマットを作ってみました。

ここで公開している情報は《Base62のような何か》です。「Base62」という規格化された公知の仕様ではありません。本サイトの著者が勝手に考案して、適当に実装した自己満足ライブラリです。脆弱性や特許侵害等の安全性検証はしていません。ご利用は自己責任でお願いします。

ダウンロード

base62.zip

ライブラリ

C++版

std::string base62_encode(unsigned char const *ptr, size_t len)

バイナリ列を《Base62のような何か》文字列に変換します。バイナリ列は unsigned char 配列と長さを取ります。結果の《Base62のような何か》文字列はstd::stringで返します。

bool base62_decode(char const *ptr, size_t len, std::vector<unsigned char> *out)

《Base62のような何か》文字列をバイナリ列に変換します。《Base62のような何か》文字列は char 配列と長さを取ります。結果のバイナリ列は std::vector<unsigned char> に格納されます。成功した場合はtrueを返し、入力文字列が不正の場合にはfalseを返します。

JavaScript版

function base62_encode(u8a)

バイナリ列を《Base62のような何か》文字列に変換します。バイナリ列はUint8Arrayオブジェクトを渡します。結果の《Base62のような何か》文字列はStringオブジェクトを返します。

function base62_decode(str)

《Base62のような何か》文字列をバイナリ列に変換します。《Base62のような何か》文字列はStringオブジェクトを渡します。結果のバイナリ列はUint8Arrayオブジェクトを返します。入力文字列が不正の場合にはnullを返します。

アルゴリズム

入力バイナリデータを8バイトごとに区切り、符号無し64ビット整数とし、62の剰余を11個求め、[0-9A-Za-z]の62種類の文字に割り当てて出力します。これを小ブロックとします。56バイト(小ブロック7個)をひとまとめとして大ブロックを構成し、大ブロックの先頭に1バイトのヘッダが付与されます。ヘッダにはその大ブロック内に格納されているバイト数を[0-9A-Za-z]で表現します。ヘッダの値が0のとき、データの終了を意味します。ヘッダの値が57以上の場合は未定義です。

変換元のデータが8の倍数または56の倍数のときに、変換後の文字列の無駄が最小となり、変換効率が最大となります。

入力バイナリデータが56バイトのとき、変換後文字列は78バイトとなります。