理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

ASCII Armoredとはどんなエンコーディングであるのか

バイナリのデータを 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 言語での実装例が記載されています。完全引用すると以下の通り。

      #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」された文字列になります。