- [[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
を使ってみた次第。
まあちょっと知っておくと便利かもということで今日この間調べたことをまとめてみました。