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を使ってみた次第。

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

nyarla が大体

Scrapbox でコメントや意見を書く