バイナリのデータを ASCII として転送する方法には、みんな大好き Base64 以外にもいろいろな方法があります。この方法の一つとして、PGP の ASCII Armor という方法があるようなのですが、全然知らなかったので調べてみました。
- PGP ASCII Armor とは 調べてみる限り、RFC 4880 OpenPGP Message Format で定義されている方法です。具体的には 6 章の Radix-64 になります。そしてこれ、wikipedia:Base64 の「変形版」の節に記載のあることから分かるように、Base64 の亜種になります。
もうちょっと正確に言うと、Radix-64 は、base64 と CRC の組み合わせから構成されています。Base64 については、RFC 2045 を参照すれば良いですし、簡単なエンコード方法であることから、インターネット上にも大量に Base64 のエンコード方法は転がっていますのでそちらを参照。この Blog でも、7 年前くらいに Perl で実装を書いてました。 一方で、CRC は言ってみれば誤り検出用に付加される符号になります。Radix-64 で使用する PGP については、RFC 4880 の 6.1. An Implementation of the CRC-24 in "C" で C 言語での実装例が記載されています。完全引用すると以下の通り。
|c| #define CRC24_INIT 0xB704CEL #define CRC24_POLY 0x1864CFBL
typedef long crc24;
crc24 crc_octets(unsigned char *octets, size_t len)
{
crc24 crc = CRC24_INIT;
int i;
while (len--) {
crc ^= (*octets++) << 16;
for (i = 0; i < 8; i++) {
crc <<= 1;
if (crc & 0x1000000)
crc ^= CRC24_POLY;
}
}
return crc & 0xFFFFFFL;
}
||<
元々のデータに対する CRC をこのような実装を用いて 24 bit の値として算出し、Base64 変換した上で、元々のデータの Base64 変換した値に "=" とともに連結します。これがいわゆる「ASCII armored」された文字列になります。