カラクリサイクル

『輝かしい青春』なんて失かった人の雑記

Perlスクリプトにバイナリファイル埋め込む方法

概要: Perlのスクリプトのバイナリファイルをテキストで埋め込む


しばらく前の話になりますが、この前に書いたGoogle App Engineでホスト名を効率よく取得する方法を考える という記事内の二個目の方法を実現するスクリプトをこの間の記事を書いた後に書いたとき、 画像ファイルをpsgiスクリプトに埋め込むということが必要になったので、そのとき調べたことを今日書いてみます。

まず、画像ファイルをテキスト、つまりバイナリファイルをテキストファイルとして表現するには、 uuencodeというフォーマットがあるらしいです。

で、Perlでバリナリファイルをこのuuencode文字列に変換するには、

#!perl

use strict;
use warings;

my $file = shift @ARGV;

open( my $fh, '<', $file ) or die "Cannot open file: ${file}: ${!}";
binmode $fh;
my $data = do { local $/; <$fh> };
close $fh;

my $text = pack('u*', $data);

print $text;

というスクリプトを例えばbin2text.plという感じで用意して、

$ ./bin2text.pl {binaryfile}

という感じで実行すれば、uuencodeのデータ部分が取得できます。

んで、このテキストをバイナリに戻すには、

#!perl

use strict;
use warnings;

my $source = q{uuencode形式のデータ};
my $binary = unpack('u*', $source);

という感じになります。

んで、例えばpsgiスクリプトか何かで、テキスト化された画像バイナリファイルを返すには、

#!perl

use strict;
use warnings;

# 1 x 1の透明なgifファイル
my $image   = unpack('u*', q{K1TE&.#EA`0`!`(```/_______R'Y!`$*``$`+``````!``$```("3`$`.P``});
my $length  = legnth($image);

return sub {
    return [
        200,
        [
            'Content-Type'      => 'image/gif',
            'Content-Length'    => $length,
        ],
        [ $image ]
    ]
};

という感じになります。

でこの間書いたって言ってる 任意のホストにファイルにアクセスしてきた人のIPアドレスとリモートホストを送信するスクリプトでは、 要約すれなこんな感じの方法でWebビーコンを返しています。

まあこのuuencodeっていう形式は大昔に使われてた形式らしくて、今はBase64がメジャーらしいのですが、 ちょっとしたスクリプトで使うためにMIME::Base64使うのもアレなのでuuencodeを使ってみた次第。

まあちょっと知っておくと便利かもということで今日この間調べたことをまとめてみました。